*** crossfire-0.94.0//CHANGES	Sun Feb  8 05:26:27 1998
--- crossfire-0.94.1/CHANGES	Sun Apr 12 22:05:49 1998
***************
*** 1,3 ****
--- 1,141 ----
+ Changes from Crossfire 0.94.0 to 0.94.1:
+ 
+ in artifacts file - moved some settings of difficulty before Object line.
+ (difficulty after the Object line have no effect)
+ 
+ In low level socket code, retry read/write again if we get a EWOULDBLOCK
+ in addition to EAGAIN errors.  Some systems return EAGAIN, others EWOULDBLOCK
+ 
+ Fixed possible crash in move_monsters.  I believe the problem was that
+ the monster got killed by a door, and the function was not expecting
+ it, and would use the invalid object.  Not sure if the code I put in will
+ really fix the problem, or just migrate it to a higher level calling
+ function (have not seen the crash myself)
+ 
+ If on linux, include crypt.h in main.c
+ 
+ Various minor memory leaks fixed.
+ 
+ Better error message for non wiz people trying to use shutdown command.
+ Shutdown command actually added to command structures and is now usuable.
+ 
+ Internal animations changed from explicit defines to use SET_ANIMATION
+ macro.  Much easier to read, and better supports client side animations.
+ 
+ Include sounds.h/sound calls no matter what RPLAY is set to.  Only
+ rplay special code is in sounds.h.  This way, client can still get sound
+ information without rplay being defined.
+ 
+ removed NPC_PROG code - not used at all - only thing there was a few
+ #ifdefs setting values.
+ 
+ Moved typedefs for function pointer stuff from structs.h to funcpoint.h.
+ No outside affect on code, just makes more sense internally.
+ 
+ Disable default selection of DEBUG_DMALLOC on crosssite.def
+ 
+ Removed old/unused charisma bonus values from common/living.c
+ 
+ Minor fix so that a space is properly added between item number and name.
+ 
+ Added a lex loading routine.  Performance seems to be roughly the same,
+ but ease of maintenace/readability seems better to me.  Modifications to
+ loader.c should not be done - instead, they should be done to loader.l
+ Loader directive flags and loader return flags added to loader.l - those
+ are now used instead of arbitrary integer values.
+ 
+ Fix c_wix.c dm goto command to set the destination object/map name.  Otherwise,
+ if an invalid map was entered, the enter_exit would try to print a null
+ string - some systems handle this OK, others will crash.
+ 
+ Changed common/time.c to use GETTIMEOFDAY macro defined once at top
+ of file instead of having #ifdefs throughout the file.
+ 
+ Fix so that items of differing values will not be merged.  Also, when
+ merging objects, do not clear startequip flag.
+ 
+ Fix in doc/playbook-html so all include directives are handled properly
+ with the include_html.pl script.
+ 
+ More details printed about improved weapons (how many improvements done,
+ max number of improvements.)  Also, skills will show how many improvements
+ the character can handle.
+ 
+ Bargaining skill will be auto applied when in shops.
+ 
+ Change teleporter code so the teleporter does not have to be the first
+ or second item on the space - teleporter can be any object on the space.
+ 
+ -a, -u apply options added (always apply/unapply instead of toggling).
+ Internally, apply and apply_special have been changed to take one more option
+ which is this flag.
+ 
+ Applied rings will not be merged - instead they will remain seperate.  Fixes
+ problems with getting full bonuses, and also makes it easier to apply/unapply
+ one item.
+ 
+ Increased frequency of generation for strange ring (nodrain ring).  This
+ should make it appear probably roughly as often as the ring of life,
+ or maybe even more often.
+ 
+ Put maximum carry limit in - beyond the limit, a character can carry no more.
+ This limit is fairly high right now, but should improve playbalance and
+ prevent characters from getting a negative weight or carrying so much
+ stuff it takes forever to move (session appears hung to them)
+ 
+ Added CS_STAT_WEIGHT_LIM to newclient.h, so client can know how much
+ the player can handle (only used for GUI, so it can do a carry/limit
+ type of thing)
+ 
+ Title information now used in hiscore displays.
+ 
+ Show invisible spell will now make handles visible.
+ 
+ New server code won't crash if player does nothing when it prompts for the
+ name.  Also, include necessary dummy functions so server will compile
+ of ERIC_SERVER is not set.
+ 
+ Will now search keyrings when running into special doors for matching
+ keys (players can protect keys by putting them in other containers.)
+ 
+ Change jump skill so that any spaces with FLY_ON set will affect
+ the jumping player.  This prevents the character from jumping over
+ player movers.
+ 
+ In create_wall - if insertion if the initial wall fails (new all is destroyed),
+ don't extend the wall.  Fixes the earthwall on top of pool of chaos which
+ creates strange map problems.
+ 
+ Map fixes:
+      Lake_Country/ebony/masterlev altar should now accept fragment
+ 	of chaos.
+     Put no magic areas in apartment so it should no longer be able
+ 	to dimension door and get keys.  
+     /city/houses/wizz.entry should now be entered at the correct position.
+     /city/misc/library - library cards are now identified, so it should
+ 	no longer be able to buy then sell at a profit.
+     /city/houses/wizz* maps:  removed ./ from start of some map paths -
+ 	causes apparant problems.
+     Lake_Country/Butakis/blacksmith - can no longer get free dragon mails
+ 	or other items - have to pay for them now.
+     Remove pup_land/rainbow/Lv4/\nkey (\n was an embedded newline).  Map
+ 	doesn't look to be needed.
+ 
+ Archetype changes:
+ 
+ Added blocksview to gwall so you can no longer see through them.
+ 
+ Fixed up castle animation in bitmap mode (212/312 images needed to be swapped)
+ 
+ Increased exp for skulls from 3500 to 5000, reduced exp of deathtrees from
+ 1400 to 1000.
+ 
+ fixed typo in gauntlets which meant title was set right.
+ 
+ aggressive 1 values changed to unagressive 0 values in some archetypes
+ (no such value as agressive)
+ 
+ ------------------------------------------------------------------------------
  Changes from Crossfire 0.93.7 to 0.94.0:
  
  Added outline of future versions in the TODO file.
*** crossfire-0.94.0//CREDITS	Sun Feb  8 05:26:27 1998
--- crossfire-0.94.1/CREDITS	Mon Mar  9 09:21:20 1998
***************
*** 1,6 ****
  Source:
    crossfire: (try "crossfire -v")
!     Presently maintained by Mark Wedel (master@rahul.net)
      Original code by Frank Tore Johansen (frankj@ifi.uio.no)
      _Lots_ of additions, improvements, bugfixes, patches, etc, by:
        kjetilho@ifi.uio.no (Kjetil Torgrim Homme)
--- 1,6 ----
  Source:
    crossfire: (try "crossfire -v")
!     Presently maintained by Mark Wedel (mark@pyramid.com)
      Original code by Frank Tore Johansen (frankj@ifi.uio.no)
      _Lots_ of additions, improvements, bugfixes, patches, etc, by:
        kjetilho@ifi.uio.no (Kjetil Torgrim Homme)
***************
*** 43,48 ****
--- 43,50 ----
        thomas@astro.psu.edu (Brian Thomas)
        jsm@axon.ksc.nasa.gov (John Steven Moerk)
        swedel@tymnet.com (Scott Wedel)
+       s-nisita@urdr.ics.es.osaka-u.ac.jp (Nishita Seikoh)
+       stieber@informatik.tu-muenchen.de (Christian Stieber)
  
    crossclient:
      Frank Tore Johansen
***************
*** 58,63 ****
--- 60,67 ----
      Lars Henrik Olafsen (larso@ifi.uio.no)
    Spell-documentation:
      Chris Carpinello (chrisc@cs.odu.edu)
+   Handbook (Playbook)
+     Brian Thomas (thomas@astro.psu.edu)
  
  Graphics:
    Vidar Lund (vidarl@ifi.uio.no) [Did all the *cool* graphics]
*** crossfire-0.94.0//DEVELOPERS	Sun Feb  8 05:26:27 1998
--- crossfire-0.94.1/DEVELOPERS	Sun Mar  1 02:30:43 1998
***************
*** 6,12 ****
  
  Peter Mardahl <peterm@soda.berkeley.edu> runes, new spells, changing
  	of spell parameters, new archetypes
! Brian Thmoas (thomas@astro.psu.edu)- Skills, alchemy, altars
  Phil Brown (phil@bolthole.com)- Java Client
  
   The following poeple have contributed a lot to Crossfire in the past,
--- 6,12 ----
  
  Peter Mardahl <peterm@soda.berkeley.edu> runes, new spells, changing
  	of spell parameters, new archetypes
! Brian Thomas (thomas@astro.psu.edu)- Skills, alchemy, altars
  Phil Brown (phil@bolthole.com)- Java Client
  
   The following poeple have contributed a lot to Crossfire in the past,
*** crossfire-0.94.0//README	Sun Feb  8 05:26:28 1998
--- crossfire-0.94.1/README	Sun Mar  1 09:30:41 1998
***************
*** 19,27 ****
    Crossfire has been known to compile on the following systems
    (latest known version number of Crossfire that compiled on these
    systems is included in parantheses):
!   o Sun4 with Solaris 2.5 (using gcc) (latest)
!   o Pyramid DC/OSx [cd]079,[cd]087 (latest)
!   o PC Compatible, with Linux 2.0 (redhat 3.0.3, gcc) (latest)
    o PC Compatible, with Linux 1.2.13 (0.92.4)
    o Sun4 with SunOS 4.1.3 (0.92.2)
    o Sun4 with Solaris 2.x (0.92.0)
--- 19,28 ----
    Crossfire has been known to compile on the following systems
    (latest known version number of Crossfire that compiled on these
    systems is included in parantheses):
!   o PC Compatible, with Linux 2.1 (gcc, glibc) (latest)
!   o Pyramid DC/OSx [cd]087,Reliant Unix 5.43C (latest)
!   o Silicon Graphics, Irix  6.3 (standard cc) 0.94.0
!   o Sun4 with Solaris 2.5 (with gcc) (0.93.7)
    o PC Compatible, with Linux 1.2.13 (0.92.4)
    o Sun4 with SunOS 4.1.3 (0.92.2)
    o Sun4 with Solaris 2.x (0.92.0)
*** crossfire-0.94.0//TODO	Sun Feb  8 05:26:28 1998
--- crossfire-0.94.1/TODO	Mon Mar  9 05:22:18 1998
***************
*** 15,20 ****
--- 15,25 ----
  however it keeps growing as various problems are discovered that
  don't have an easy fix.
  
+ - Add/change door handling - make them more real life - they stick around,
+   can be opened, closed, different keys for different doors, etc.  This
+   sort of mimics the gate behaviour, except keys may need to open them, etc.
+ - Added armor quality, with armor being damaged as it is used.  Add repair
+   shops to go with this.
  - Change players draining exp from others.  Currently, there are problems
    in that it not adjusted based on levels, so there are various abuses
    draining from low level characters.  Also, generally it is not possibled
*** crossfire-0.94.0//common/Imakefile	Sun Feb  8 05:26:15 1998
--- crossfire-0.94.1/common/Imakefile	Thu Apr 16 01:57:06 1998
***************
*** 1,6 ****
  /*   CrossFire, A Multiplayer game for X-windows
   *
!  *   $Id: Imakefile,v 1.16 1998/01/05 10:23:32 master Exp $
   *
   *   Copyright (C) 1992 Frank Tore Johansen
   *
--- 1,6 ----
  /*   CrossFire, A Multiplayer game for X-windows
   *
!  *   $Id: Imakefile,v 1.17 1998/04/12 21:19:05 master Exp master $
   *
   *   Copyright (C) 1992 Frank Tore Johansen
   *
***************
*** 40,46 ****
  	item.c\
  	links.c\
  	living.c\
- 	loader.c\
  	logger.c\
  	los.c\
  	ltostr.c\
--- 40,45 ----
***************
*** 57,63 ****
  	treasure.c\
  	xutil.c
  
! OBJS = $(SRCS:.c=.o)
  
  all:: $(OBJS)
  
--- 56,62 ----
  	treasure.c\
  	xutil.c
  
! OBJS = $(SRCS:.c=.o) loader.o
  
  all:: $(OBJS)
  
***************
*** 76,89 ****
  	cextract +Ap -P -o ../include/libproto.h.bak -I$(INCROOT) $(INCLUDES) \
  	-I/usr/local/lib/gcc-include -cpp-program="gcc -E -C" \
  	$(SRCS)
! 	sed -e "s/#if __STDC__/#ifdef __STDC__/" -e "s/__signed/signed/g" -e "/__inline/d" < ../include/libproto.h.bak > ../include/libproto.h
  	chmod 664 ../include/libproto.h
  	$(RM) ../include/libproto.h.bak
  
! InsertArchive(README Imakefile $(SRCS),common)
  
  patchlist::
! 	@echo README Imakefile $(SRCS) > .patchlist
  
  doc:
  	rm -f ../doc/crosslib.doc
--- 75,91 ----
  	cextract +Ap -P -o ../include/libproto.h.bak -I$(INCROOT) $(INCLUDES) \
  	-I/usr/local/lib/gcc-include -cpp-program="gcc -E -C" \
  	$(SRCS)
! 	sed -e "s/#if __STDC__/#ifdef __STDC__/" -e "s/__signed/signed/g" -e "/__inline/d" -e "/YY_BUFFER/d" < ../include/libproto.h.bak > ../include/libproto.h
  	chmod 664 ../include/libproto.h
  	$(RM) ../include/libproto.h.bak
  
! InsertArchive(README Imakefile $(SRCS) loader.l loader.c,common)
  
  patchlist::
! 	@echo README Imakefile $(SRCS) loader.l > .patchlist
! 
! loader.c: loader.l
! 	flex -i -t loader.l > loader.c
  
  doc:
  	rm -f ../doc/crosslib.doc
*** crossfire-0.94.0//common/arch.c	Sun Feb  8 05:26:15 1998
--- crossfire-0.94.1/common/arch.c	Thu Apr 16 02:02:10 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_arch_c =
!  *   "$Id: arch.c,v 1.29 1998/02/07 23:04:44 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_arch_c =
!  *   "$Id: arch.c,v 1.30 1998/04/12 21:06:55 master Exp master $";
   */
  
  /*
***************
*** 28,33 ****
--- 28,37 ----
  #include <global.h>
  #include <arch.h>
  #include <funcpoint.h>
+ #include <loader.h>
+ 
+ /* IF set, does a little timing on the archetype load. */
+ #define TIME_ARCH_LOAD 0
  
  static archetype *arch_table[ARCHTABLE];
  int arch_cmp=0;		/* How many strcmp's */
***************
*** 160,184 ****
  void first_arch_pass(FILE *fp) {
    object *op;
    archetype *at,*prev=NULL,*last_more=NULL;
!   int i;
  
    op=get_object();
    op->arch=first_archetype=at=get_archetype_struct();
!   while((i=load_object(fp,op))) {
      copy_object(op,&at->clone);
      at->clone.speed_left= -0.1;
      switch(i) {
!     case 1: /* A new archetype, just link it with the previous */
        if(last_more!=NULL)
          last_more->next=at;
        if(prev!=NULL)
          prev->next=at;
        prev=last_more=at;
        break;
      case 2:
        LOG(llevError,"Error: Archetype with inventory is illegal!\n");
        exit(-1);
!     case 3: /* Another part of the previous archetype, link it correctly */
        at->head=prev;
        at->clone.head = &prev->clone;
        if(last_more!=NULL) {
--- 164,191 ----
  void first_arch_pass(FILE *fp) {
    object *op;
    archetype *at,*prev=NULL,*last_more=NULL;
!   int i,first=2;
  
    op=get_object();
    op->arch=first_archetype=at=get_archetype_struct();
!   while((i=load_object(fp,op,first))) {
!     first=0;
      copy_object(op,&at->clone);
      at->clone.speed_left= -0.1;
      switch(i) {
!     case LL_NORMAL: /* A new archetype, just link it with the previous */
        if(last_more!=NULL)
          last_more->next=at;
        if(prev!=NULL)
          prev->next=at;
        prev=last_more=at;
        break;
+ #if 0
      case 2:
        LOG(llevError,"Error: Archetype with inventory is illegal!\n");
        exit(-1);
! #endif
!     case LL_MORE: /* Another part of the previous archetype, link it correctly */
        at->head=prev;
        at->clone.head = &prev->clone;
        if(last_more!=NULL) {
***************
*** 253,276 ****
   */
  
  void load_archetypes() {
!   FILE *fp;
!   char filename[MAX_BUF];
!   int comp;
! 
!   sprintf(filename,"%s/%s",settings.libdir,settings.archetypes);
!   LOG(llevDebug,"Reading archetypes from %s...\n",filename);
!   if((fp=open_and_uncompress(filename,0,&comp))==NULL) {
!     LOG(llevError,"Can't open archetype file.\n");
!     return;
!   }
!   /*setlinebuf (fp);*/
!   clear_archetable();
!   LOG(llevDebug,"arch-pass 1...");
!   first_arch_pass(fp);
    LOG(llevDebug,"done\n");
    init_archetable();
    warn_archetypes=1;
!   rewind(fp);
    LOG(llevDebug,"loading treasure...");
    load_treasures();
    LOG(llevDebug,"done\narch-pass 2...");
--- 260,304 ----
   */
  
  void load_archetypes() {
!     FILE *fp;
!     char filename[MAX_BUF];
!     int comp;
! #if 1
!     struct timeval tv1,tv2;
! #endif
! 
!     sprintf(filename,"%s/%s",settings.libdir,settings.archetypes);
!     LOG(llevDebug,"Reading archetypes from %s...\n",filename);
!     if((fp=open_and_uncompress(filename,0,&comp))==NULL) {
! 	LOG(llevError,"Can't open archetype file.\n");
! 	return;
!     }
!     clear_archetable();
!     LOG(llevDebug,"arch-pass 1...");
! #if TIME_ARCH_LOAD
!     gettimeofday(&tv1, NULL);
! #endif
!     first_arch_pass(fp);
! #if TIME_ARCH_LOAD
!     { int sec, usec;
! 	gettimeofday(&tv2, NULL);
! 	sec = tv2.tv_sec - tv1.tv_sec;
! 	usec = tv2.tv_usec - tv1.tv_usec;
! 	if (usec<0) { usec +=1000000; sec--;}
! 	LOG(llevDebug,"Load took %d.%06d seconds\n", sec, usec);
!      }
! #endif
! 
    LOG(llevDebug,"done\n");
    init_archetable();
    warn_archetypes=1;
! 
!   /* do a close and reopen instead of a rewind - necessary in case the
!    * file has been compressed.
!    */
!   close_and_delete(fp, comp);
!   fp=open_and_uncompress(filename,0,&comp);
! 
    LOG(llevDebug,"loading treasure...");
    load_treasures();
    LOG(llevDebug,"done\narch-pass 2...");
*** crossfire-0.94.0//common/button.c	Sun Feb  8 05:26:15 1998
--- crossfire-0.94.1/common/button.c	Sun Apr 12 21:08:21 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_button_c =
!  *   "$Id: button.c,v 1.31 1998/02/07 23:10:51 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_button_c =
!  *   "$Id: button.c,v 1.31 1998/02/07 23:10:51 master Exp $";
   */
  
  /*
*** crossfire-0.94.0//common/glue.c	Sun Feb  8 05:26:15 1998
--- crossfire-0.94.1/common/glue.c	Sun Apr 12 21:10:23 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_glue_c =
!  *   "$Id: glue.c,v 1.19 1998/02/07 23:20:07 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_glue_c =
!  *   "$Id: glue.c,v 1.20 1998/04/12 21:08:22 master Exp master $";
   */
  
  /*
***************
*** 45,51 ****
  type_func_ob	draw_stats_func;
  type_func_ob	draw_inventory_func;
  type_func_ob	draw_look_func;
! type_int_func_ob_ob	apply_func;
  type_func_ob	draw_func;
  type_func_ob_ob	monster_check_apply_func;
  type_func_ob	draw_inventory_faces_func;
--- 45,51 ----
  type_func_ob	draw_stats_func;
  type_func_ob	draw_inventory_func;
  type_func_ob	draw_look_func;
! type_int_func_ob_ob_int	apply_func;
  type_func_ob	draw_func;
  type_func_ob_ob	monster_check_apply_func;
  type_func_ob	draw_inventory_faces_func;
***************
*** 88,94 ****
    draw_look_faces_func = dummy_function_ob;
    draw_inventory_func = dummy_function_ob;
    draw_look_func = dummy_function_ob;
!   apply_func = dummy_function_ob2int;
    draw_func = dummy_function_ob;
    monster_check_apply_func = dummy_function_ob2;
    init_blocksview_players_func = dummy_function;
--- 88,94 ----
    draw_look_faces_func = dummy_function_ob;
    draw_inventory_func = dummy_function_ob;
    draw_look_func = dummy_function_ob;
!   apply_func = dummy_int_function_ob_ob_int;
    draw_func = dummy_function_ob;
    monster_check_apply_func = dummy_function_ob2;
    init_blocksview_players_func = dummy_function;
***************
*** 213,219 ****
   * Specify which function to call to apply an object.
   */
  
! void set_apply(type_int_func_ob_ob addr) {
    apply_func = addr;
  }
  
--- 213,219 ----
   * Specify which function to call to apply an object.
   */
  
! void set_apply(type_int_func_ob_ob_int addr) {
    apply_func = addr;
  }
  
***************
*** 332,337 ****
--- 332,341 ----
  }
  
  void dummy_function_int_ob_ob (int n, object *ob, object *ob2) {
+ }
+ 
+ int dummy_int_function_ob_ob_int (object *ob, object *ob2, int n) {
+ return 0;
  }
  
  #endif
*** crossfire-0.94.0//common/init.c	Sun Feb  8 05:26:15 1998
--- crossfire-0.94.1/common/init.c	Sun Apr 12 21:10:24 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_init_c =
!  *   "$Id: init.c,v 1.23 1998/02/07 23:20:31 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_init_c =
!  *   "$Id: init.c,v 1.23 1998/02/07 23:20:31 master Exp $";
   */
  
  /*
*** crossfire-0.94.0//common/item.c	Sun Feb  8 05:26:15 1998
--- crossfire-0.94.1/common/item.c	Sun Apr 12 21:11:52 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_item_c =
!  *   "$Id: item.c,v 1.41 1998/02/07 23:49:53 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_item_c =
!  *   "$Id: item.c,v 1.42 1998/04/12 21:10:25 master Exp master $";
   */
  
  /*
***************
*** 215,222 ****
  	/* if nrof==1, then get_number returns 'a'. Add an 'n' if appropriate*/
  	if(op->nrof==1&&QUERY_FLAG(op,FLAG_AN))
  	    strcat(buf,"n");
- 	strcat(buf, " ");
  #endif
  	strcat(buf,op->name);
  	if (op->nrof != 1) {
  	    char *buf3 = strstr(buf, " of ");
--- 215,222 ----
  	/* if nrof==1, then get_number returns 'a'. Add an 'n' if appropriate*/
  	if(op->nrof==1&&QUERY_FLAG(op,FLAG_AN))
  	    strcat(buf,"n");
  #endif
+ 	if (op->nrof!=1) strcat(buf, " ");
  	strcat(buf,op->name);
  	if (op->nrof != 1) {
  	    char *buf3 = strstr(buf, " of ");
***************
*** 579,584 ****
--- 579,588 ----
            sprintf(buf,"(ac%+d)",op->stats.ac);
            strcat(retbuf,buf);
          }
+ 	if (op->type==WEAPON && op->level>0) {
+ 	  sprintf(buf,"(improved %d/%d)",op->last_eat,op->level);
+           strcat(retbuf,buf);
+ 	}
          break;
        default:
          break;
*** crossfire-0.94.0//common/living.c	Sun Feb  8 05:26:15 1998
--- crossfire-0.94.1/common/living.c	Sun Apr 12 21:14:25 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_living_c =
!  *   "$Id: living.c,v 1.45 1998/02/07 23:30:26 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_living_c =
!  *   "$Id: living.c,v 1.46 1998/04/12 21:11:54 master Exp master $";
   */
  
  /*
***************
*** 48,95 ****
    30,40,50,70,100
  };
  
! /* At around a 59 bonus, under the present system, it possible to make
!  * money by buying an item then selling it.  I smoothed out the
!  * increments some, making the gains more linear.  Before, in some cases,
!  * the gain of a point might increase the bonus by 4, but the next point
!  * gained only increased it by 2.  Now, for almost all positive bonuses,
!  * it is increased by 3 per point.
!  * Cost of buying an item is (6*(100-cha_bonus))/100
!  * Cost of selling an item is 100/(100-cha_bonus)
!  * This, it costs (60000-1200cha_bonus+6*cha_bonus^2)/10000 to buy something
!  * than to sell something.
!  * Various numbers of interest:
!  * bonus	buy/sell value	cha to have that bonus
!  * -100		24
!  * -83		20.09		 (0)
!  * -59		15.17		 (2)
!  * -29		9.98		 (5)
!  *   0		6.00		(12)
!  *   8		5.08		(14)
!  *  18		4.03		(18)
!  *  29		3.02		(21)
!  *  42		2.02		(26)
!  *  59		1.009		(30+)
!  *
!  * What this shows is that a penalty is very harsh, and actual benefit
!  * is of a diminishing nature.  Thus, I changed the cha_bonus so that
!  * penalties are no longer so bad - a player should never have to pay more
!  * than about 10 times to buy an item than what he gets for selling it.
!  */
! #if 0	/* old bonus */
! int cha_bonus[MAX_STAT + 1]={
!   -80,-70,-60,-50,-40,-30,-25,-20,-15,-10,-7,-3,0,4,7,10,13,16,19,22,25,28,31,
!    34,37,40,43,46,49,52,55
! };
! 
! /* old bonus, but not as old as the one above */
! int cha_bonus[MAX_STAT + 1]={
!   -35,-32,-29,-26,-23,-20,-17,-14,-11,-8,-5,-2,1,4,7,10,13,16,19,22,25,28,31,
!    34,37,40,43,46,49,52,55
! };
! #endif
! 
! /* 0.92.7 Changed way charisma works (ignore above.)  Values now 
   * represent how much more it costs to buy something than to sell it
   * (10, a value of 10 means it is that if it costs 50 gp to buy, you
   * would only get 5 gp when you sell.)  Let query_cost do the calculations
--- 48,54 ----
    30,40,50,70,100
  };
  
! /* 0.92.7 Changed way charisma works.  Values now 
   * represent how much more it costs to buy something than to sell it
   * (10, a value of 10 means it is that if it costs 50 gp to buy, you
   * would only get 5 gp when you sell.)  Let query_cost do the calculations
***************
*** 114,134 ****
--- 73,119 ----
  int dex_bonus[MAX_STAT + 1]={
    -4,-3,-2,-2,-1,-1,-1,0,0,0,0,0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,6,6,7
  };
+ 
+ /* speed_bonus uses dex as its stat */
  float speed_bonus[MAX_STAT + 1]={
    -0.4, -0.4, -0.3, -0.3, -0.2, -0.2, -0.2, -0.1, -0.1, -0.1, -0.05, 0, 0, 0,
    0.05, 0.1, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.8, 1.0, 1.2, 1.4,
    1.6, 1.8, 2.0, 2.5, 3.0
  };
+ 
+ /* dam_bonus, thaco_bonus, max_carry, weight limit all are based on
+  * strength.
+  */
  int dam_bonus[MAX_STAT + 1]={
    -2,-2,-2,-1,-1,-1,0,0,0,0,0,0,1,1,1,2,2,2,3,3,3,4,4,5,5,6,6,7,8,10,15
  };
  int thaco_bonus[MAX_STAT + 1]={
    -2,-2,-1,-1,0,0,0,0,0,0,0,0,0,0,1,1,1,2,2,2,3,3,3,4,4,5,5,6,7,8,10
  };
+ 
+ /* Max you can carry before you start getting extra speed penalties */
  int max_carry[MAX_STAT + 1]={
    2,4,7,11,16,22,29,37,46,56,67,79,92,106,121,137,154,172,191,211,232,254,277,
    301,326,352,400,450,500,600,1000
  };
+ 
+ /* weight_limit - the absolute most a character can carry - a character can't
+  * pick stuff up if it would put him above this limit.
+  * value is in grams, so we don't need to do conversion later
+  * These limits are probably overly generous, but being there were no values
+  * before, you need to start someplace.
+  */
+ 
+ int weight_limit[MAX_STAT+ 1] = {
+     200000,  /* 0 */
+     250000,300000,350000,400000,500000,	    /* 5*/
+     600000,700000,800000,900000,1000000,    /* 10 */
+     1100000,1200000,1300000,1400000,1500000,/* 15 */
+     1650000,1800000,1950000,2100000,2250000,/* 20 */
+     2400000,2550000,2700000,2850000,3000000, /* 25 */
+     3250000,3500000,3750000,4000000,4500000  /*30 */ 
+ };
+ 
  int learn_spell[MAX_STAT + 1]={
    0,0,0,1,2,4,8,12,16,25,36,45,55,65,70,75,80,85,90,95,100,100,100,100,100,
    100,100,100,100,100,100
***************
*** 1264,1269 ****
--- 1249,1259 ----
      op->speed=max;
  
    if(op->type == PLAYER) {
+     /* f is a number the represents the number of kg above (positive num)
+      * or below (negative number) that the player is carrying.  If above
+      * weight limit, then player suffers a speed reduction based on how
+      * much above he is, and what is max carry is
+      */
      f=(op->carrying/1000)-max_carry[op->stats.Str];
      if(f>0) op->speed=op->speed/(1.0+f/max_carry[op->stats.Str]);
    }
*** crossfire-0.94.0//common/map.c	Sun Feb  8 05:26:15 1998
--- crossfire-0.94.1/common/map.c	Sun Apr 12 21:15:08 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_map_c =
!  *   "$Id: map.c,v 1.51 1997/08/14 08:55:48 master Exp $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_map_c =
!  *   "$Id: map.c,v 1.52 1998/04/12 21:14:38 master Exp master $";
   */
  
  /*
***************
*** 32,37 ****
--- 32,39 ----
  #include <dirent.h>
  #endif
  
+ #include <loader.h>
+ 
  extern int nrofallocobjects,nroffreeobjects;
  
  #if defined (MACH) || defined (NeXT) || defined (__MACH__)
***************
*** 592,598 ****
      op=get_object();
      op->map = m; /* To handle buttons correctly */
  
!     while((i=load_object(fp,op))) {
  	/* if the archetype for the object is null, means that we
  	 * got an invalid object.  Don't do anythign with it - the game
  	 * or editor will not be able to do anything with it either.
--- 594,600 ----
      op=get_object();
      op->map = m; /* To handle buttons correctly */
  
!     while((i=load_object(fp,op,LO_REPEAT))) {
  	/* if the archetype for the object is null, means that we
  	 * got an invalid object.  Don't do anythign with it - the game
  	 * or editor will not be able to do anything with it either.
***************
*** 611,627 ****
  		LOG(llevDebug,"Baptized altar to %s\n",op->title);
  #endif
  	switch(i) {
! 	  case 1:
  	    insert_ob_in_map(op,m);
  	    if (op->inv) fix_container(op);
  	    prev=op,last_more=op;
  	    break;
! 
  	  case 2:
  	    op = insert_ob_in_ob(op,prev);
  	    break;
! 
! 	  case 3:
  	    insert_ob_in_map(op,m);
  	    op->head=prev,last_more->more=op,last_more=op;
  	    break;
--- 613,633 ----
  		LOG(llevDebug,"Baptized altar to %s\n",op->title);
  #endif
  	switch(i) {
! 	  case LL_NORMAL:
  	    insert_ob_in_map(op,m);
+ #if 1
+ 	    if (op->inv) sum_weight(op);
+ #else
  	    if (op->inv) fix_container(op);
+ #endif
  	    prev=op,last_more=op;
  	    break;
! #if 0	/* internal inventories should be handled by load routine */
  	  case 2:
  	    op = insert_ob_in_ob(op,prev);
  	    break;
! #endif
! 	  case LL_MORE:
  	    insert_ob_in_map(op,m);
  	    op->head=prev,last_more->more=op,last_more=op;
  	    break;
***************
*** 768,774 ****
          
      op = get_object();
  
!     if (!load_object(fp, op) || op->type != MAP) {
  	LOG(llevError,"Error in map (%s) - map object not found\n", filename);
          close_and_delete(fp, comp);
  	return (NULL);
--- 774,780 ----
          
      op = get_object();
  
!     if (!load_object(fp, op,LO_NEWFILE) || op->type != MAP) {
  	LOG(llevError,"Error in map (%s) - map object not found\n", filename);
          close_and_delete(fp, comp);
  	return (NULL);
***************
*** 836,842 ****
      
      op = get_object();
  
!     load_object(fp,op);
      if (op->arch == NULL || op->type != MAP) {
  	LOG(llevError,"Error in temporary map '%s'\n", m->path);
          m = load_original_map(m->path,0);
--- 842,848 ----
      
      op = get_object();
  
!     load_object(fp,op,LO_NEWFILE);
      if (op->arch == NULL || op->type != MAP) {
  	LOG(llevError,"Error in temporary map '%s'\n", m->path);
          m = load_original_map(m->path,0);
***************
*** 974,979 ****
--- 980,986 ----
      m->in_memory=MAP_LOADING;
      if (m->tmpname == NULL)    /* if we have loaded unique items from */
        delete_unique_items(m); /* original map before, don't duplicate them */
+     load_object(fp, NULL, LO_NOREAD);
      load_objects (m, fp, 0);
      close_and_delete(fp, comp);
      m->in_memory=MAP_IN_MEMORY;
***************
*** 1362,1367 ****
--- 1369,1375 ----
    if (m->buttons)
      free_objectlinkpt(m->buttons);
    m->buttons = NULL;
+   if (m->tmpname) free(m->tmpname); m->tmpname=NULL;
  }
  
  /*
*** crossfire-0.94.0//common/object.c	Sun Feb  8 05:26:15 1998
--- crossfire-0.94.1/common/object.c	Sun Apr 12 21:16:44 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_object_c =
!  *   "$Id: object.c,v 1.54 1998/02/07 23:33:06 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_object_c =
!  *   "$Id: object.c,v 1.55 1998/04/12 21:15:09 master Exp master $";
   */
  
  /*
***************
*** 108,114 ****
  	(ob1->immune != ob2->immune) ||
  	(ob1->vulnerable != ob2->vulnerable) || 
  	(ob1->magic != ob2->magic) ||
! 	(ob1->slaying != ob2->slaying))
  	    return 0;
  
      switch (ob1->type) {
--- 108,115 ----
  	(ob1->immune != ob2->immune) ||
  	(ob1->vulnerable != ob2->vulnerable) || 
  	(ob1->magic != ob2->magic) ||
! 	(ob1->slaying != ob2->slaying) ||
! 	(ob1->value != ob2->value)) 
  	    return 0;
  
      switch (ob1->type) {
***************
*** 116,123 ****
  	    if (ob1->level != ob2->level) return 0;
  	    break;
  
- 	case POTION:
  	case RING:
  	case AMULET:
  	    /* This should compare the value of the stats, and not the pointer
  	     * itself.  There can be cases were potions seem to loose their
--- 117,136 ----
  	    if (ob1->level != ob2->level) return 0;
  	    break;
  
  	case RING:
+ 	    /* Don't merge applied rings - easier to keep them seperate, and
+ 	     * it makes more sense (can easily unapply one ring).  Rings are
+ 	     * the only objects that need this special code, as they are the
+ 	     * only objects of the same type in which more than 1 can be
+ 	     * applied at a time.
+ 	     *
+ 	     * Note - there is no break so we fall into the POTION/AMULET
+ 	     * check below.
+ 	     */
+ 	    if (QUERY_FLAG(ob1, FLAG_APPLIED) || QUERY_FLAG(ob2, FLAG_APPLIED))
+ 		return 0;
+ 
+ 	case POTION:
  	case AMULET:
  	    /* This should compare the value of the stats, and not the pointer
  	     * itself.  There can be cases were potions seem to loose their
***************
*** 504,513 ****
    op->expmul=1.0;
    op->direction=0;
    op->glow_radius=0;
- #ifdef NPC_PROG
-   op->npc_status=0;
-   op->npc_program=0;
- #endif
    op->stats.Str=op->stats.Dex=op->stats.Con=0;
    op->stats.Wis=op->stats.Cha=op->stats.Int=op->stats.Pow=0;
    op->material=op->magic=op->state=op->type=0;
--- 517,522 ----
***************
*** 1132,1138 ****
      }
      if(QUERY_FLAG(op,FLAG_FLYING)?QUERY_FLAG(tmp,FLAG_FLY_OFF):
        QUERY_FLAG(tmp,FLAG_WALK_OFF))
!         (*apply_func)(op,tmp);
  
      /* Eneq(@csd.uu.se): Fixed this to skip tmp->above=tmp */
  
--- 1141,1147 ----
      }
      if(QUERY_FLAG(op,FLAG_FLYING)?QUERY_FLAG(tmp,FLAG_FLY_OFF):
        QUERY_FLAG(tmp,FLAG_WALK_OFF))
!         (*apply_func)(op,tmp,0);
  
      /* Eneq(@csd.uu.se): Fixed this to skip tmp->above=tmp */
  
***************
*** 1174,1180 ****
      if (CAN_MERGE(op,top))
      {
        top->nrof+=op->nrof;
!       CLEAR_FLAG(top,FLAG_STARTEQUIP);
        op->weight = 0; /* Don't want any adjustements now */
        remove_ob(op);
        free_object(op);
--- 1183,1189 ----
      if (CAN_MERGE(op,top))
      {
        top->nrof+=op->nrof;
! /*      CLEAR_FLAG(top,FLAG_STARTEQUIP);*/
        op->weight = 0; /* Don't want any adjustements now */
        remove_ob(op);
        free_object(op);
***************
*** 1352,1358 ****
        if (CAN_MERGE(op,tmp))
        {
          op->nrof+=tmp->nrof;
!         CLEAR_FLAG(op,FLAG_STARTEQUIP);
          remove_ob(tmp);
          free_object(tmp);
        }
--- 1361,1367 ----
        if (CAN_MERGE(op,tmp))
        {
          op->nrof+=tmp->nrof;
! /*        CLEAR_FLAG(op,FLAG_STARTEQUIP);*/
          remove_ob(tmp);
          free_object(tmp);
        }
***************
*** 1844,1850 ****
        if(op->type==PLAYER)
          (*draw_func)(op);
  #endif
!       if((*apply_func)(op,tmp)==2)
          break;
        }
    }
--- 1853,1859 ----
        if(op->type==PLAYER)
          (*draw_func)(op);
  #endif
!       if((*apply_func)(op,tmp,0)==2)
          break;
        }
    }
*** crossfire-0.94.0//common/player.c	Sun Feb  8 05:26:15 1998
--- crossfire-0.94.1/common/player.c	Sun Apr 12 21:17:18 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_player_c =
!  *   "$Id: player.c,v 1.32 1998/02/07 23:42:53 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_player_c =
!  *   "$Id: player.c,v 1.33 1998/04/12 21:16:44 master Exp master $";
   */
  
  /*
***************
*** 143,148 ****
--- 143,149 ----
    new->draw_run_on=0;
    new->show_buttons=0;
    new->last_flags=0;
+   new->last_weight_limit=0;
    return new;
  }
  
***************
*** 179,184 ****
--- 180,186 ----
    for(i=0;i<COMMAND_HASH_SIZE;i++) {
      for (key=pl->keys[i]; key; key=nextkey) {
  	nextkey = key->next;
+ 	if (key->params) free(key->params);
  	free(key);
      }
      pl->keys[i] = NULL;
*** crossfire-0.94.0//common/time.c	Sun Feb  8 05:26:15 1998
--- crossfire-0.94.1/common/time.c	Sun Apr 12 21:18:07 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_time_c =
!  *    "$Id: time.c,v 1.11 1996/03/04 09:25:10 master Exp $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_time_c =
!  *    "$Id: time.c,v 1.12 1998/04/12 21:17:19 master Exp master $";
   */
  
  /*
***************
*** 50,61 ****
  long process_utime_long_count;
  #endif
  
! /* Solaris 2.5 wants 2 arguments for gettimeofday - fake it out here until
!  * I can determine if earlier version of solaris do in fact only have 1
!  * argument.
   */
! #if defined(__sun__) && defined(SVR4)
! #define gettimeofday(last_time) gettimeofday(last_time, (struct timezone *) NULL);
  #endif
  
  /*
--- 50,64 ----
  long process_utime_long_count;
  #endif
  
! /* 0.94.1 - change to GETTIMEOFDAY macro - SNI systems only one one option.
!  * rather than have complex #ifdefs throughout the file, lets just figure
!  * it out once, here at the top.
   */
! 
! #if (defined(__sun__) && defined(SVR4)) || defined(linux)
! #define GETTIMEOFDAY(last_time) gettimeofday(last_time, (struct timezone *) NULL);
! #else
! #define GETTIMEOFDAY(last_time) gettimeofday(last_time);
  #endif
  
  /*
***************
*** 76,86 ****
    pticks = 0;
  #endif
  
! #if defined(__sun__) && defined(SVR4)
!   (void) gettimeofday(&last_time);
! #else
!   (void) gettimeofday(&last_time, (struct timezone *) NULL);
! #endif
  }
  
  void
--- 79,85 ----
    pticks = 0;
  #endif
  
!   (void) GETTIMEOFDAY(&last_time);
  }
  
  void
***************
*** 110,120 ****
    static struct timeval new_time;
    long elapsed_utime;
  
! #if defined(__sun__) && defined(SVR4)
!   (void) gettimeofday(&new_time);
! #else
!   (void) gettimeofday(&new_time, (struct timezone *) NULL);
! #endif
    elapsed_utime = (new_time.tv_sec - last_time.tv_sec) * 1000000 +
                    new_time.tv_usec - last_time.tv_usec;
    if (elapsed_utime > max_time) {
--- 109,116 ----
    static struct timeval new_time;
    long elapsed_utime;
  
!   (void) GETTIMEOFDAY(&new_time);
! 
    elapsed_utime = (new_time.tv_sec - last_time.tv_sec) * 1000000 +
                    new_time.tv_usec - last_time.tv_usec;
    if (elapsed_utime > max_time) {
***************
*** 139,149 ****
    static struct timeval new_time;
    long sleep_sec, sleep_usec;
  
! #if defined(__sun__) && defined(SVR4)
!   (void) gettimeofday(&new_time);
! #else
!   (void) gettimeofday(&new_time, (struct timezone *) NULL);
! #endif
    sleep_sec = last_time.tv_sec - new_time.tv_sec;
    sleep_usec = max_time - (new_time.tv_usec - last_time.tv_usec);
  
--- 135,142 ----
    static struct timeval new_time;
    long sleep_sec, sleep_usec;
  
!   (void) GETTIMEOFDAY(&new_time);
! 
    sleep_sec = last_time.tv_sec - new_time.tv_sec;
    sleep_usec = max_time - (new_time.tv_usec - last_time.tv_usec);
  
***************
*** 244,253 ****
  {
    struct timeval now;
  
! #if defined(__sun__) && defined(SVR4)
!   (void) gettimeofday(&now);
! #else
!   (void) gettimeofday(&now, (struct timezone *) 0);
! #endif
    return now.tv_sec;
  }
--- 237,242 ----
  {
    struct timeval now;
  
!   (void) GETTIMEOFDAY(&now);
    return now.tv_sec;
  }
*** crossfire-0.94.0//common/treasure.c	Sun Feb  8 05:26:15 1998
--- crossfire-0.94.1/common/treasure.c	Sun Apr 12 21:18:21 1998
***************
*** 1,7 ****
  
  /*
   * static char *rcs_treasure_c =
!  *   "$Id: treasure.c,v 1.49 1998/02/07 23:48:34 master Exp master $";
   */
  
  /*
--- 1,7 ----
  
  /*
   * static char *rcs_treasure_c =
!  *   "$Id: treasure.c,v 1.50 1998/04/12 21:18:07 master Exp master $";
   */
  
  /*
***************
*** 42,47 ****
--- 42,48 ----
  #include <treasure.h>
  #include <spellist.h>
  #include <funcpoint.h>
+ #include <loader.h>
  
  /*
   * Initialize global archtype pointers:
***************
*** 1013,1019 ****
      else if (!strncmp(cp, "Object",6)) {
  	art->item = (object *) malloc(sizeof(object));
  	reset_object(art->item);
!         if (!load_object(fp, art->item))
  	   LOG(llevError,"Init_Artifacts: Could not load object.\n");
  	art->item->name = add_string((strchr(cp, ' ')+1));
  	al=find_artifactlist(art->item->type);
--- 1014,1020 ----
      else if (!strncmp(cp, "Object",6)) {
  	art->item = (object *) malloc(sizeof(object));
  	reset_object(art->item);
!         if (!load_object(fp, art->item,LO_LINEMODE))
  	   LOG(llevError,"Init_Artifacts: Could not load object.\n");
  	art->item->name = add_string((strchr(cp, ' ')+1));
  	al=find_artifactlist(art->item->type);
*** /dev/null	Thu Mar  5 08:08:09 1998
--- crossfire-0.94.1/common/loader.l	Sun Apr 12 21:20:42 1998
***************
*** 0 ****
--- 1,1476 ----
+ %{
+ /*
+  * static char *rcsid_object_c =
+  *   "$Id: loader.l,v 1.1 1998/04/12 21:19:42 master Exp master $";
+  */
+ 
+ /*
+     CrossFire, A Multiplayer game for X-windows
+ 
+     Copyright (C) 1994 Mark Wedel
+     Copyright (C) 1992 Frank Tore Johansen
+ 
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation; either version 2 of the License, or
+     (at your option) any later version.
+ 
+     This program is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+ 
+     You should have received a copy of the GNU General Public License
+     along with this program; if not, write to the Free Software
+     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ 
+     The author can be reached via e-mail to master@rahul.net
+ */
+ 
+ /* Eneq(@csd.uu.se): Added weight-modifiers in environment of objects.
+    sub/add_weight will transcend the environment updating the carrying
+    variable. */
+ 
+ 
+ #include <global.h>
+ #include <loader.h>
+ #include <newserver.h>
+ 
+ #define NEW_LOAD
+ 
+ /* All the variable names.  Each entry should correspond to the 
+  * V_ vlaue in loader.h (that is, the 20'th value in this array should
+  * correspond to the 20'th V_(value) in loader.h)  The V_??? get
+  * used as indexes into this array.
+  */
+ 
+ /* If you change this list (add/delete/rename), also update the list
+  * in crossedit/Attr.c, around line 360.  That list is the variables
+  * that can be set in crossedit for various objects.
+  */
+ static char *variable_const[NR_OF_VARIABLES] = {
+   "Object","name","race","slaying","msg","endmsg",
+   "Inventory","arch","other_arch","More",
+   "anim","mina","end","last_heal","last_sp","last_grace","last_eat",
+   "speed","speed_left","slow_move",
+   "face","Str","Dex","Con","Wis","Cha","Int","Pow","hp","maxhp","sp","maxsp",
+   "grace","maxgrace",
+   "exp","food","dam","wc","ac","x","y","nrof","level","direction",
+   "type","material","value", "weight","carrying",
+   "immune","protected","attacktype","vulnerable",
+   "path_attuned","path_repelled","path_denied",
+   "invisible","magic","state","alive","applied","unpaid","need_an","need_ie",
+   "no_pick","no_pass","walk_on","walk_off","fly_on","fly_off","is_animated",
+   "flying","monster",
+   "friendly","generator","is_thrown","auto_apply","treasure",
+   "apply_once","see_invisible","can_roll","is_turning","is_turnable",
+   "is_used_up","identified","reflecting","changing","splitting","hitback",
+   "startequip","blocksview","editable","undead","scared","unaggressive",
+   "reflect_missile","reflect_spell","no_magic",
+   "wiz","was_wiz","no_fix_player","tear_down", "luck",
+   "run_away","pass_thru",
+   "can_pass_thru","pick_up","anim_speed","container","no_drop",
+   "no_pretext","will_apply","random_movement", "can_apply",
+   "can_cast_spell","can_use_scroll","can_use_wand","can_use_bow",
+   "can_use_armour","can_use_weapon","can_use_ring","has_ready_wand",
+   "has_ready_bow","xrays","is_floor","lifesave","no_strength",
+   "sleep","stand_still","random_move","only_attack","armour",
+   "attack_movement","move_state","confused","stealth","connected",
+   "cursed","damned","see_anywhere","known_magical","known_cursed",
+   "can_use_skill","been_applied","title","has_ready_rod","can_use_rod",
+   "has_ready_horn","can_use_horn","expmul",
+   "unique","make_invisible","inv_locked",
+   "is_wooded","is_hilly","has_ready_skill","has_ready_weapon",
+   "no_skill_ident","glow_radius","is_blind","can_see_in_dark",
+   "is_cauldron","randomitems","is_dust", "no_steal",
+ #ifdef NPC_PROG
+   "npc_status","npc_program",
+ #endif
+ };
+ 
+ #define YY_DECL int lex_load(object *op)
+ 
+ static char *yval();
+ static int add_animation(char *name, int num_faces, Fontindex faces[]);
+ 
+ #define FREE_AND_COPY(sv,nv) { if (sv) free_string(sv); sv=add_string(nv); }
+ #define SET_OR_CLEAR_FLAG(op, flag, val) \
+ 	{ if (val) SET_FLAG(op, flag); else CLEAR_FLAG(op, flag); }
+ 
+ #define IVAL	atoi(yval())
+ #define FVAL	atof(yval())
+ 
+ %}
+ 
+ 
+ 
+ S	[ \t]+.+
+ WS	[ \t]*
+ 
+ %x MESSAGE ANIMATION
+ 
+ /* Don't have to link with -lfl with this */
+ %option noyywrap
+ 
+ /* need yy_push_state, yy_pop_state */
+ %option stack
+ 
+ %%
+ 
+ %{
+ /* Declare some local variables */
+     char msgbuf[HUGE_BUF];
+     int ismore=0,anim_start=0;
+     Fontindex faces[MAX_ANIMATIONS];
+ 
+ %}
+ 
+ ^anim{WS}$	    {	BEGIN( ANIMATION ); 
+ 			if (op->arch==NULL) {
+ 			    LOG(llevError,"Got animation in object without archetype.\n");
+ 			    return LL_IGNORED;
+ 			}
+ 			SET_FLAG(op,FLAG_ANIMATE);
+ 			anim_start=0;
+ 		    }
+ 
+ <ANIMATION>^mina{WS}$ {	BEGIN( INITIAL );
+ 			op->arch->animation_id=add_animation(op->arch->name,
+ 						anim_start, faces);
+ 		    }
+ <ANIMATION>\n+      {}
+ <ANIMATION>.+       { faces[anim_start++] = FindFace(yytext,0); }
+ 
+ 
+ ^msg{WS}$	    {	BEGIN( MESSAGE ); msgbuf[0]='\0'; }
+ <MESSAGE>^endmsg{WS}$ {	BEGIN( INITIAL );
+ 			op->msg=add_string(msgbuf);
+ 			/* Just print a warning so we can be reasonably safe
+ 			 * about not overflowing the buffer.
+ 			 */
+ 			if (strlen(op->msg) > (HUGE_BUF/2))
+ 			    LOG(llevDebug, "\n\tWarning message length > %d (max allowed=%d): %d\n>%.80s<\n",
+ 				HUGE_BUF/2, HUGE_BUF, strlen(op->msg),op->msg);
+ 		    }
+ <MESSAGE>.*	    {strcat(msgbuf, yytext); strcat(msgbuf,"\n"); }
+ 
+ 
+ ^object{S}	    {	char *yv=yval();
+ 
+ 			if (*yv=='\0') {
+ 			    LOG(llevError,"Object lacks name.\n");
+ 			    return LL_IGNORED;
+ 			}
+ 			if (op->arch!=NULL) op->arch->name=add_string(yv);
+ 			op->name = add_string(yv);
+ 		    }
+ 
+ ^name{S}	    {	char *yv=yval();
+ 
+ 			if (*yv=='\0') LOG(llevError,"Name without val\n");
+ 			else FREE_AND_COPY(op->name, yv);
+ 		    }
+ ^race{S}	    FREE_AND_COPY(op->race,yval());
+ ^slaying{S}	    FREE_AND_COPY(op->slaying, yval());
+ ^inventory.*$	    LOG(llevError,"Got depreciated Inventory command?\n");
+ 
+ 
+ ^arch{S}         {	/* If op->arch has been set, then this new object
+ 			 * must be part of the inventory.  So process
+ 			 * appropriately.
+ 			 */
+ 			if (op->arch) {
+ 			    object *tmp;
+ 
+ 			    tmp=get_object();
+ 			    tmp->arch = find_archetype(yval());
+ 			    if (tmp->arch!=NULL) 
+ 				copy_object(&tmp->arch->clone,tmp);
+ 			    lex_load(tmp);
+ 			    insert_ob_in_ob(tmp,op);
+ 			}
+ 			/* This is the actual archetype definition then */
+ 			else {
+ 			    op->arch=find_archetype(yval());
+ 			    if (op->arch!=NULL) copy_object(&op->arch->clone,op);
+ 			}
+ 		    }
+ 
+ ^other_arch{S}        op->other_arch=find_archetype(yval());
+ ^more{WS}$	    { /* We need to record that this is a multipart object,
+ 		       * so the calling function can glue things back together
+ 		       */
+ 			ismore=1;
+ 		    }
+ 
+ ^end{WS}$	    { if (ismore) return LL_MORE; else return LL_NORMAL; }
+ ^last_heal{S}	    op->last_heal = IVAL;
+ ^last_sp{S}	    op->last_sp = IVAL;
+ ^last_grace{S}    op->last_grace = IVAL;
+ ^last_eat{S}	    op->last_eat = IVAL;
+ ^speed{S}	    {	op->speed = FVAL;
+ 			if (op->speed<0) op->speed_left = op->speed_left-RANDOM()%100/100.0;
+ 			update_ob_speed(op);
+ 		    }
+ ^speed_left{S}    op->speed_left = FVAL;
+ ^slow_move{S}	    {	SET_SLOW_PENALTY(op,FVAL);
+ 			SET_FLAG(op, FLAG_SLOW_MOVE);
+ 		    }
+ ^face{S}	    op->face = &new_faces[FindFace(yval(), 0)];
+ ^str{S}		op->stats.Str = IVAL;
+ ^dex{S}		op->stats.Dex = IVAL;
+ ^con{S}		op->stats.Con = IVAL;
+ ^wis{S}		op->stats.Wis = IVAL;
+ ^cha{S}		op->stats.Cha = IVAL;
+ ^int{S}		op->stats.Int = IVAL;
+ ^pow{S}		op->stats.Pow = IVAL;
+ ^hp{S}		op->stats.hp = IVAL;
+ ^maxhp{S}	op->stats.maxhp = IVAL;
+ ^sp{S}		op->stats.sp = IVAL;
+ ^maxsp{S}	op->stats.maxsp = IVAL;
+ ^grace{S}	op->stats.grace = IVAL;
+ ^maxgrace{S}	op->stats.maxgrace = IVAL;
+ ^exp{S}		op->stats.exp = atol(yval());
+ ^food{S}	op->stats.food = IVAL;
+ ^dam{S}		op->stats.dam = IVAL;
+ ^wc{S}		op->stats.wc = IVAL;
+ ^ac{S}		op->stats.ac = IVAL;
+ ^x{S}		{op->x = IVAL; op->ox= op->x; }
+ ^y{S}		{op->y = IVAL; op->oy= op->y; }
+ ^nrof{S}	op->nrof= atol(yval());
+ ^level{S}	op->level = IVAL;
+ ^direction{S}	op->direction = IVAL;
+ ^type{S}	op->type = IVAL;
+ ^material{S}	op->material = IVAL;
+ ^value{S}	op->value = IVAL;
+ ^weight{S}	op->weight = atol(yval());
+ ^carrying{S}	op->carrying = atol(yval());
+ ^immune{S}	op->immune = IVAL;
+ ^protected{S}	op->protected = IVAL;
+ ^attacktype{S}  op->attacktype = IVAL;
+ ^vulnerable{S}    op->vulnerable = IVAL;
+ ^path_attuned{S}  op->path_attuned = IVAL;
+ ^path_repelled{S} op->path_repelled = IVAL;
+ ^path_denied{S}   op->path_denied = IVAL;
+ ^invisible{S}	    op->invisible = IVAL;
+ ^magic{S}	    op->magic = IVAL;
+ ^state{S}	    op->state = IVAL;
+ ^alive{S}	    SET_OR_CLEAR_FLAG(op, FLAG_ALIVE, IVAL);
+ ^applied{S}	    SET_OR_CLEAR_FLAG(op, FLAG_APPLIED, IVAL);
+ ^unpaid{S}	    SET_OR_CLEAR_FLAG(op, FLAG_UNPAID, IVAL);
+ ^need_an{S}	    SET_OR_CLEAR_FLAG(op, FLAG_AN, IVAL);
+ ^need_ie{S}	    SET_OR_CLEAR_FLAG(op, FLAG_NEED_IE, IVAL);
+ ^no_pick{S}	    SET_OR_CLEAR_FLAG(op, FLAG_NO_PICK, IVAL);
+ ^no_pass{S}	    SET_OR_CLEAR_FLAG(op, FLAG_NO_PASS, IVAL);
+ ^walk_on{S}	    SET_OR_CLEAR_FLAG(op, FLAG_WALK_ON, IVAL);
+ ^walk_off{S}	    SET_OR_CLEAR_FLAG(op, FLAG_WALK_OFF, IVAL);
+ ^fly_on{S}	    SET_OR_CLEAR_FLAG(op, FLAG_FLY_ON, IVAL);
+ ^fly_off{S}	    SET_OR_CLEAR_FLAG(op, FLAG_FLY_OFF, IVAL);
+ ^is_animated{S}	    SET_OR_CLEAR_FLAG(op, FLAG_ANIMATE, IVAL);
+ ^flying{S}	    SET_OR_CLEAR_FLAG(op, FLAG_FLYING, IVAL);
+ ^monster{S}	    SET_OR_CLEAR_FLAG(op, FLAG_MONSTER, IVAL);
+ ^friendly{S}	    {	if (IVAL) {
+ 			    SET_FLAG(op, FLAG_FRIENDLY);
+ 			    if (op->type != PLAYER) {
+ 				LOG(llevDebug,"Adding friendly object %s.\n",op->name);
+ 				add_friendly_object(op);
+ 			    }
+ 			}
+ 			else CLEAR_FLAG(op, FLAG_FRIENDLY);
+ 		    }
+ ^generator{S}	    SET_OR_CLEAR_FLAG(op, FLAG_GENERATOR, IVAL);
+ ^is_thrown{S}	    SET_OR_CLEAR_FLAG(op, FLAG_IS_THROWN, IVAL);
+ ^auto_apply{S}	    SET_OR_CLEAR_FLAG(op, FLAG_AUTO_APPLY, IVAL);
+ ^treasure{S}	    SET_OR_CLEAR_FLAG(op, FLAG_TREASURE, IVAL);
+ ^apply_once{S}	    SET_OR_CLEAR_FLAG(op, FLAG_APPLY_ONCE, IVAL);
+ ^see_invisible{S}   SET_OR_CLEAR_FLAG(op, FLAG_SEE_INVISIBLE, IVAL);
+ ^can_roll{S} 	    SET_OR_CLEAR_FLAG(op, FLAG_CAN_ROLL, IVAL);
+ ^is_turning{S}	    SET_OR_CLEAR_FLAG(op, FLAG_IS_TURNING, IVAL);
+ ^is_turnable{S}	    SET_OR_CLEAR_FLAG(op, FLAG_IS_TURNABLE, IVAL);
+ ^is_used_up{S}	    SET_OR_CLEAR_FLAG(op, FLAG_IS_USED_UP, IVAL);
+ ^identified{S}	    {	if (IVAL) {
+ 			    SET_FLAG(op, FLAG_IDENTIFIED);
+ 			    CLEAR_FLAG(op, FLAG_KNOWN_MAGICAL);
+ 			}
+ 			else CLEAR_FLAG(op, FLAG_IDENTIFIED);
+ 		    }
+ ^reflecting{S}	    SET_OR_CLEAR_FLAG(op, FLAG_REFLECTING, IVAL);
+ ^changing{S} 	    SET_OR_CLEAR_FLAG(op, FLAG_CHANGING, IVAL);
+ ^splitting{S}	    SET_OR_CLEAR_FLAG(op, FLAG_SPLITTING, IVAL);
+ ^hitback{S}  	    SET_OR_CLEAR_FLAG(op, FLAG_HITBACK, IVAL);
+ ^startequip{S}	    SET_OR_CLEAR_FLAG(op, FLAG_STARTEQUIP, IVAL);
+ ^blocksview{S}	    SET_OR_CLEAR_FLAG(op, FLAG_BLOCKSVIEW, IVAL);
+ ^editable{S}	    op->arch->editable = IVAL;
+ ^undead{S}  	    SET_OR_CLEAR_FLAG(op, FLAG_UNDEAD, IVAL);
+ ^scared{S}  	    SET_OR_CLEAR_FLAG(op, FLAG_SCARED, IVAL);
+ ^unaggressive{S}    SET_OR_CLEAR_FLAG(op, FLAG_UNAGGRESSIVE, IVAL);
+ ^reflect_missile{S} SET_OR_CLEAR_FLAG(op, FLAG_REFL_MISSILE, IVAL);
+ ^reflect_spell{S}   SET_OR_CLEAR_FLAG(op, FLAG_REFL_SPELL, IVAL);
+ ^no_magic{S} 	    SET_OR_CLEAR_FLAG(op, FLAG_NO_MAGIC, IVAL);
+ ^wiz{S}  	    {	if (IVAL) {
+ 			    SET_FLAG(op, FLAG_WIZ);
+ 			    SET_FLAG(op, FLAG_WAS_WIZ);
+ 			    SET_FLAG(op, FLAG_WIZPASS);
+ 			}
+ 			else {
+ 			    CLEAR_FLAG(op, FLAG_WIZ);
+ 			    CLEAR_FLAG(op, FLAG_WIZPASS);
+ 			}
+ 		    }
+ ^was_wiz{S}  	    SET_OR_CLEAR_FLAG(op, FLAG_WAS_WIZ, IVAL);
+ ^no_fix_player{S}   SET_OR_CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER, IVAL);
+ ^tear_down{S}	    SET_OR_CLEAR_FLAG(op, FLAG_TEAR_DOWN, IVAL);
+ ^luck{S}  	    op->stats.luck = IVAL;
+ ^run_away{S}	    op->run_away = IVAL;
+ ^pass_thru{S}	    SET_OR_CLEAR_FLAG(op, FLAG_PASS_THRU, IVAL);
+ ^can_pass_thru{S}   SET_OR_CLEAR_FLAG(op, FLAG_CAN_PASS_THRU, IVAL);
+ ^pick_up{S}	    op->pick_up = IVAL;
+ ^anim_speed{S}	    op->anim_speed = IVAL;
+ ^container{S}	    op->weight_limit = IVAL;
+ ^no_drop{S}	    SET_OR_CLEAR_FLAG(op, FLAG_NO_DROP, IVAL);
+ ^no_pretext{S}	    SET_OR_CLEAR_FLAG(op, FLAG_NO_PRETEXT, IVAL);
+ ^will_apply{S}	    op->will_apply = IVAL;
+ ^random_movement{S}	    SET_OR_CLEAR_FLAG(op, FLAG_RANDOM_MOVE, IVAL);
+ ^can_apply{S}		    op->can_apply = IVAL;
+ ^can_cast_spell{S}	    SET_OR_CLEAR_FLAG(op, FLAG_CAST_SPELL, IVAL);
+ ^can_use_scroll{S}	    SET_OR_CLEAR_FLAG(op, FLAG_USE_SCROLL, IVAL);
+ ^can_use_wand{S}	    SET_OR_CLEAR_FLAG(op, FLAG_USE_WAND, IVAL);
+ ^can_use_bow{S}		    SET_OR_CLEAR_FLAG(op, FLAG_USE_BOW, IVAL);
+ ^can_use_armour{S}	    SET_OR_CLEAR_FLAG(op, FLAG_USE_ARMOUR, IVAL);
+ ^can_use_weapon{S}	    SET_OR_CLEAR_FLAG(op, FLAG_USE_WEAPON, IVAL);
+ ^can_use_ring{S}	    SET_OR_CLEAR_FLAG(op, FLAG_USE_RING, IVAL);
+ ^has_ready_wand{S}	    SET_OR_CLEAR_FLAG(op, FLAG_READY_WAND, IVAL);
+ ^has_ready_bow{S}   SET_OR_CLEAR_FLAG(op, FLAG_READY_BOW, IVAL);
+ ^xrays{S}	    SET_OR_CLEAR_FLAG(op, FLAG_XRAYS, IVAL);
+ ^is_floor{S}	    SET_OR_CLEAR_FLAG(op, FLAG_IS_FLOOR, IVAL);
+ ^lifesave{S}	    SET_OR_CLEAR_FLAG(op, FLAG_LIFESAVE, IVAL);
+ ^no_strength{S}	    SET_OR_CLEAR_FLAG(op, FLAG_NO_STRENGTH, IVAL);
+ ^sleep{S}	    SET_OR_CLEAR_FLAG(op, FLAG_SLEEP, IVAL);
+ ^stand_still{S}	    SET_OR_CLEAR_FLAG(op, FLAG_STAND_STILL, IVAL);
+ ^random_move{S}	    SET_OR_CLEAR_FLAG(op, FLAG_RANDOM_MOVE, IVAL);
+ ^only_attack{S}	    SET_OR_CLEAR_FLAG(op, FLAG_ONLY_ATTACK, IVAL);
+ ^armour{S}	    op->armour = IVAL;
+ ^attack_movement{S} op->move_type = IVAL;
+ ^move_state{S}	    op->move_status = IVAL;
+ ^confused{S}	    SET_OR_CLEAR_FLAG(op, FLAG_CONFUSED, IVAL);
+ ^stealth{S}	    SET_OR_CLEAR_FLAG(op, FLAG_STEALTH, IVAL);
+ ^connected{S}	    add_button_link(op, op->map, IVAL);
+ ^cursed{S}	    SET_OR_CLEAR_FLAG(op, FLAG_CURSED, IVAL);
+ ^damned{S}	    SET_OR_CLEAR_FLAG(op, FLAG_DAMNED, IVAL);
+ ^see_anywhere{S}    SET_OR_CLEAR_FLAG(op, FLAG_SEE_ANYWHERE, IVAL);
+ ^known_magical{S}   SET_OR_CLEAR_FLAG(op, FLAG_KNOWN_MAGICAL, IVAL);
+ ^known_cursed{S}    SET_OR_CLEAR_FLAG(op, FLAG_KNOWN_CURSED, IVAL);
+ ^can_use_skill{S}   SET_OR_CLEAR_FLAG(op, FLAG_CAN_USE_SKILL, IVAL);
+ ^been_applied{S}    SET_OR_CLEAR_FLAG(op, FLAG_BEEN_APPLIED, IVAL);
+ ^title{S}	    {	char *y=yval();
+ 			if (*y=='\0') LOG(llevError,"Title without value.\n");
+ 			else FREE_AND_COPY(op->title, y);
+ 		    }
+ ^has_ready_rod{S}	SET_OR_CLEAR_FLAG(op, FLAG_READY_ROD, IVAL);
+ ^can_use_rod{S}		SET_OR_CLEAR_FLAG(op, FLAG_USE_ROD, IVAL);
+ ^has_ready_horn{S}	SET_OR_CLEAR_FLAG(op, FLAG_READY_HORN, IVAL);
+ ^can_use_horn{S}	SET_OR_CLEAR_FLAG(op, FLAG_USE_HORN, IVAL);
+ ^expmul{S}		op->expmul = FVAL;
+ ^unique{S}		SET_OR_CLEAR_FLAG(op, FLAG_UNIQUE, IVAL);
+ ^make_invisible{S}	SET_OR_CLEAR_FLAG(op, FLAG_MAKE_INVIS, IVAL);
+ ^inv_locked{S}		SET_OR_CLEAR_FLAG(op, FLAG_INV_LOCKED, IVAL);
+ ^is_wooded{S}		SET_OR_CLEAR_FLAG(op, FLAG_IS_WOODED, IVAL);
+ ^is_hilly{S}		SET_OR_CLEAR_FLAG(op, FLAG_IS_HILLY, IVAL);
+ ^has_ready_skill{S}	SET_OR_CLEAR_FLAG(op, FLAG_READY_SKILL, IVAL);
+ ^has_ready_weapon{S}	SET_OR_CLEAR_FLAG(op, FLAG_READY_WEAPON, IVAL);
+ ^no_skill_ident{S}	SET_OR_CLEAR_FLAG(op, FLAG_NO_SKILL_IDENT, IVAL);
+ ^glow_radius{S}		op->glow_radius = IVAL;
+ ^is_blind{S}		SET_OR_CLEAR_FLAG(op, FLAG_BLIND, IVAL);
+ ^can_see_in_dark{S}	SET_OR_CLEAR_FLAG(op, FLAG_SEE_IN_DARK, IVAL);
+ ^is_cauldron{S}		SET_OR_CLEAR_FLAG(op, FLAG_IS_CAULDRON, IVAL);
+ ^randomitems{S}		op->randomitems = find_treasurelist(yval());
+ ^is_dust{S}		SET_OR_CLEAR_FLAG(op, FLAG_DUST, IVAL);
+ ^no_steal{S}		SET_OR_CLEAR_FLAG(op, FLAG_NO_STEAL, IVAL);
+ 
+ 
+ ^can_knockback{S}	{ /* Some archetypes have these values in them */ }
+ ^can_parry{S}		{ /* Probably the pupland archetypes - I imagined */ }
+ ^can_impale{S}		{ /* That these are for the new combat code */ }
+ ^can_cut{S}		{ /* just ignore for now */ }
+ ^can_dam_armour{S}	{ }
+ 
+ <*>(^{WS}$)|\n		{/* ignore empty lines, newlines we don't do above */}
+ #.*\n			{}
+ <<EOF>>			return LL_EOF;
+ .*			yyerror( "Unrecognized string" );
+ %%
+ 
+ int yyerror(char *s)
+ {
+   LOG(llevError, "%s: %s\n", s, yytext);
+   return 0;
+ }
+ 
+ 
+ /* Our save file syntax is very simple, so we can use a very simple
+  * processing mechanism here instead using something like bison
+  * This skips over the space and returns the value, or "" if no value
+  * is found.
+  */
+ static char *yval()
+ {
+     static char *em="";
+     char *cp;
+ 
+     cp=strchr(yytext,' ');
+     if (cp) return cp+1;
+     else return em;
+ }
+ 
+ 
+ #ifdef NEW_LOAD
+ /*
+  * Loads an object from the given file-pointer.
+  * Variables will be read and parsed and patched into the object
+  * until the string "end" is reached, or the end of the file.
+  *
+  * bufstat is used to determine various file attributes:
+  *  LO_REPATE (0): We are reading from the same buffer as the last call.
+  *  LO_LINEMODE (1): file that is being read from is multi purpose (ie, other functions
+  *	will also be reading from this (treasure file, artifacts.)
+  *  LO_NEWFILE (2): This is the first read from a particular file, so the buffers should
+  *	be reset.
+  *  LO_NOREAD (3): Reset the buffers, but don't read from it. (op can be null)
+  *
+  */
+ 
+ int load_object(FILE *fp, object *op, int bufstate) {
+     int retval;
+     char inbuf[MAX_BUF];
+ 
+     if (bufstate==LO_NEWFILE || bufstate==LO_NOREAD) {
+ 	LOG(llevDebug,"Switching lex buffers\n");
+ 	yy_delete_buffer(YY_CURRENT_BUFFER);
+ 	yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));
+ 	if (bufstate==LO_NOREAD) return LL_NORMAL;
+     } 
+     if (bufstate==LO_LINEMODE) {
+ 	YY_BUFFER_STATE  yybufstate;
+ 	while (fgets(inbuf, MAX_BUF-3, fp)) {
+ 	    yybufstate=yy_scan_string(inbuf);
+ 	    retval=lex_load(op);
+ 	    yy_delete_buffer(yybufstate);
+ 	    if (retval==LL_NORMAL) return retval;
+ 	}
+ 	LOG(llevDebug,"Got eof while scanning strings\n");
+ 	return LL_EOF;
+     }
+ 
+     retval=lex_load(op);
+ /*    LOG(llevDebug,"load completed, object=%s\n",op->name);*/
+     return retval;
+ }
+ 
+ 
+ /* This takes a buffer, scans it for variables, and sets those variables
+  * as appropriate in op.
+  *
+  * This function appears to be used in only 2 places - in crossedit to
+  * override values and in c_wiz to mutate values.
+  */
+ int set_variable(object *op,char *buf) {
+     YY_BUFFER_STATE  yybufstate,yycurbuf=YY_CURRENT_BUFFER;
+     int retval;
+ 
+     yy_push_state(INITIAL);
+     yybufstate=yy_scan_string(buf);
+     retval=lex_load(op);
+     yy_switch_to_buffer(yycurbuf);
+     yy_delete_buffer(yybufstate);
+     yy_pop_state();
+     return retval;
+ }
+ #endif
+ 
+ /* Start of C code */
+ 
+ char *variables[NR_OF_VARIABLES];
+ 
+ /* This array equates the FLAG_ values with the V_ values.  Use -1 to
+  * put gaps in the array that should not be processed.
+  * The order matches the order of the define values in 'define.h'.
+  */
+ 
+ int flag_links[NUM_FLAGS+1][2] ={
+ {FLAG_ALIVE, V_ALIVE}, {FLAG_WIZ, V_WIZ},
+ {-1, -1}, {-1, -1},	/* REMOVED and FREED flags */
+ {FLAG_WAS_WIZ, V_WAS_WIZ}, {FLAG_APPLIED, V_APPLIED},
+ {FLAG_UNPAID, V_UNPAID}, {FLAG_AN, V_NEED_AN},
+ {FLAG_NO_PICK, V_NO_PICK}, {FLAG_WALK_ON, V_WALK_ON},
+ {FLAG_NO_PASS, V_NO_PASS},{FLAG_ANIMATE, V_IS_ANIMATED},
+ {FLAG_SLOW_MOVE, -1}, {FLAG_FLYING, V_FLYING},
+ {FLAG_MONSTER, V_MONSTER}, {FLAG_FRIENDLY, V_FRIENDLY},
+ {FLAG_GENERATOR, V_GENERATOR}, {FLAG_IS_THROWN, V_IS_THROWN},
+ {FLAG_AUTO_APPLY, V_AUTO_APPLY}, {FLAG_TREASURE, V_TREASURE},
+ {FLAG_APPLY_ONCE, V_APPLY_ONCE},{FLAG_SEE_INVISIBLE, V_SEE_INVISIBLE},
+ {FLAG_CAN_ROLL, V_CAN_ROLL}, {FLAG_IS_TURNING, V_IS_TURNING}, 
+ {FLAG_IS_TURNABLE, V_IS_TURNABLE},{FLAG_WALK_OFF, V_WALK_OFF},
+ {FLAG_FLY_ON, V_FLY_ON},{FLAG_FLY_OFF, V_FLY_OFF}, 
+ {FLAG_IS_USED_UP, V_IS_USED_UP}, {FLAG_IDENTIFIED, V_IDENTIFIED},
+ {FLAG_REFLECTING, V_REFLECTING}, {FLAG_CHANGING, V_CHANGING},
+ {FLAG_SPLITTING, V_SPLITTING}, {FLAG_HITBACK, V_HITBACK},
+ {FLAG_STARTEQUIP, V_STARTEQUIP}, {FLAG_BLOCKSVIEW, V_BLOCKSVIEW},
+ {FLAG_UNDEAD, V_UNDEAD}, {FLAG_SCARED, V_SCARED},
+ {FLAG_UNAGGRESSIVE, V_UNAGGRESSIVE}, {FLAG_REFL_MISSILE, V_REFLECT_MISSILE},
+ {FLAG_REFL_SPELL, V_REFLECT_SPELL}, {FLAG_NO_MAGIC, V_NO_MAGIC},
+ {FLAG_NO_FIX_PLAYER, V_NO_FIX_PLAYER}, {FLAG_NEED_IE, V_NEED_IE}, 
+ {FLAG_TEAR_DOWN, V_TEAR_DOWN}, {FLAG_RUN_AWAY, V_RUN_AWAY},
+ {FLAG_PASS_THRU, V_PASS_THRU}, {FLAG_CAN_PASS_THRU, V_CAN_PASS_THRU},
+ {FLAG_PICK_UP, V_PICK_UP}, {FLAG_UNIQUE, V_UNIQUE},
+ {FLAG_NO_DROP, V_NO_DROP}, {FLAG_NO_PRETEXT, V_NO_PRETEXT},
+ {FLAG_CAST_SPELL, V_CAN_CAST_SPELL}, {FLAG_USE_SCROLL, V_CAN_USE_SCROLL},
+ {FLAG_USE_WAND, V_CAN_USE_WAND},{FLAG_USE_BOW, V_CAN_USE_BOW},
+ {FLAG_USE_ARMOUR, V_CAN_USE_ARMOUR},{FLAG_USE_WEAPON, V_CAN_USE_WEAPON},
+ {FLAG_USE_RING, V_CAN_USE_RING}, {FLAG_READY_WAND, V_HAS_READY_WAND},
+ {FLAG_READY_BOW, V_HAS_READY_BOW}, {FLAG_XRAYS, V_XRAYS},
+ {-1, -1 /*NO_APPLY*/},  {FLAG_IS_FLOOR, V_IS_FLOOR},
+ {FLAG_LIFESAVE, V_LIFESAVE}, {FLAG_NO_STRENGTH, V_NO_STRENGTH},
+ {FLAG_SLEEP, V_SLEEP}, {FLAG_STAND_STILL, V_STAND_STILL},
+ {FLAG_RANDOM_MOVE, V_RANDOM_MOVEMENT}, {FLAG_ONLY_ATTACK, V_ONLY_ATTACK},
+ {FLAG_CONFUSED, V_CONFUSED}, {FLAG_STEALTH, V_STEALTH},
+ {-1, -1 /*WIZPASS*/}, {-1, -1 /*IS_LINKED */},
+ {FLAG_CURSED, V_CURSED}, {FLAG_DAMNED, V_DAMNED},
+ {FLAG_SEE_ANYWHERE, V_SEE_ANYWHERE}, {FLAG_KNOWN_MAGICAL, V_KNOWN_MAGICAL},
+ {FLAG_KNOWN_CURSED, V_KNOWN_CURSED}, {FLAG_CAN_USE_SKILL, V_CAN_USE_SKILL},
+ {FLAG_BEEN_APPLIED, V_BEEN_APPLIED},  {FLAG_READY_ROD, V_HAS_READY_ROD},
+ {FLAG_USE_ROD, V_CAN_USE_ROD}, {FLAG_READY_HORN, V_HAS_READY_HORN}, 
+ {FLAG_USE_HORN, V_CAN_USE_HORN},{FLAG_MAKE_INVIS,V_MAKE_INVIS},
+ {FLAG_INV_LOCKED,V_INV_LOCKED},{FLAG_IS_WOODED,V_IS_WOODED},
+ {FLAG_IS_HILLY,V_IS_HILLY},{FLAG_READY_SKILL,V_HAS_READY_SKILL},
+ {FLAG_READY_WEAPON,V_HAS_READY_WEAPON},{FLAG_NO_SKILL_IDENT,V_NO_SKILL_IDENT},
+ {FLAG_BLIND,V_BLIND},{FLAG_SEE_IN_DARK,V_SEE_IN_DARK},
+ {FLAG_IS_CAULDRON,V_IS_CAULDRON},{FLAG_DUST,V_DUST},{FLAG_NO_STEAL,V_NO_STEAL}
+ };
+ 
+ 
+ /* Adds an animation sequence to the global animation array.  We return
+  * the index number it is (to be used in animation_id).  name currently
+  * isn't used for anything, but in theory, it would be nice in the future
+  * to extend objects/artifacts so they could have something like
+  * 'animation big_diamond',  and thus have objects animated.
+  * In theory, we could probably also do checkes to see if the faces array
+  * passed to us match something already set.
+  */
+ static int add_animation(char *name, int num_faces, Fontindex faces[])
+ {
+     int i;
+ 
+     if (animations_allocated==0) {
+ 	if (!(animations=malloc(10*sizeof(Animations)))) {
+ 	    LOG(llevError,"Could not allocate space for animations - exiting\n");
+ 	    exit(1);
+ 	}
+ 	animations_allocated=9;
+ 	num_animations=1;
+ 	/* Make a default.  New animations start at one, so if something
+ 	 * thinks it is animated but hasn't set the animation_id properly,
+ 	 * it will have a default value that should be pretty obvious.
+ 	 */
+ 	animations[0].name=NULL;
+ 	animations[0].num_animations=1;
+ 	animations[0].faces = malloc(sizeof(Fontindex));
+ 	animations[0].faces[0]=0;
+     }
+     else if (num_animations==animations_allocated) {
+ 	animations=realloc(animations, sizeof(Animations)*(animations_allocated+10));
+ 	animations_allocated+=10;
+     }
+     animations[num_animations].name = add_string(name);
+     animations[num_animations].num_animations=num_faces;
+     animations[num_animations].faces = malloc(sizeof(Fontindex)*num_faces);
+     /* Maybe use a memcpy for this? */
+     for (i=0; i<num_faces; i++)
+ 	animations[num_animations].faces[i] = faces[i];
+ 
+ #if 0
+     LOG(llevDebug,"Added animation %s, index=%d, num_faces=%d\n", 
+ 	animations[num_animations].name, num_animations,num_faces);
+ #endif	
+     if (num_animations>MAXANIMNUM) {
+ 	LOG(llevError,"add_animation:num animations (%d) is greather than MAXANIMNUM (%d)\n",
+ 	    num_animations, MAXANIMNUM);
+ 	exit(1);
+     }
+     num_animations++;
+     return num_animations-1;
+ }
+ 			   
+ 
+ void save_double(char *buf,char *name,double v)
+ {
+   char tbuf[200];
+ 
+   sprintf(tbuf,"%s %f\n",name,v);
+   strcat(buf,tbuf);
+ }
+ 
+ /*
+  * Initialises the array of variable-names.  Needed before any
+  * objects can be loaded.  Called by init_library().
+  */
+ 
+ void init_vars() {
+   int i;
+   for(i=0;i<NR_OF_VARIABLES;i++)
+     variables[i]=add_string(variable_const[i]);
+ }
+ /*
+  * Returns a pointer to a static string which contains all variables
+  * which are different in the two given objects.  op is the what object
+  * the different values will be taken from.  This function is
+  * typically used to dump objects (op2=empty object), or to save objects
+  * (op2 is the objects original archetype)
+  */
+ 
+ char *get_ob_diff(object *op,object *op2) {/* I plan to optimize this heavily */
+   static char buf2[HUGE_BUF];
+   static char buf[HUGE_BUF];
+   int tmp;
+ 
+   buf[0]='\0';
+   if(op->name && op->name!=op2->name) {
+     sprintf(buf2,"name %s\n",op->name);
+     strcat(buf,buf2);
+   }
+   if(op->title && op->title!=op2->title) {
+     sprintf(buf2,"title %s\n", op->title);
+     strcat(buf, buf2);
+   }
+   if(op->race && op->race!=op2->race) {
+     sprintf(buf2,"race %s\n",op->race);
+     strcat(buf,buf2);
+   }
+   if(op->slaying && op->slaying!=op2->slaying) {
+     sprintf(buf2,"slaying %s\n",op->slaying);
+     strcat(buf,buf2);
+   }
+   if(op->msg && op->msg!=op2->msg) {
+     strcat(buf,"msg\n");
+     strcat(buf,op->msg);
+     strcat(buf,"endmsg\n");
+   }
+   if(op->other_arch!=op2->other_arch&&op->other_arch!=NULL && 
+      op->other_arch->name) {
+     sprintf(buf2,"other_arch %s\n",op->other_arch->name);
+     strcat(buf,buf2);
+   }
+   if(op->face!=op2->face) {
+       sprintf(buf2,"%s %s\n",variable_const[V_FACE], 
+ 		op->face->name);
+       strcat(buf,buf2);
+   }
+   if(op->stats.Str!=op2->stats.Str)
+     save_long(buf,variable_const[V_STR],op->stats.Str);
+   if(op->stats.Dex!=op2->stats.Dex)
+     save_long(buf,variable_const[V_DEX],op->stats.Dex);
+   if(op->stats.Con!=op2->stats.Con)
+     save_long(buf,variable_const[V_CON],op->stats.Con);
+   if(op->stats.Wis!=op2->stats.Wis)
+     save_long(buf,variable_const[V_WIS],op->stats.Wis);
+   if(op->stats.Pow!=op2->stats.Pow)
+     save_long(buf,variable_const[V_POW],op->stats.Pow);
+   if(op->stats.Cha!=op2->stats.Cha)
+     save_long(buf,variable_const[V_CHA],op->stats.Cha);
+   if(op->stats.Int!=op2->stats.Int)
+     save_long(buf,variable_const[V_INT],op->stats.Int);
+   if(op->stats.hp!=op2->stats.hp)
+     save_long(buf,variable_const[V_HP],op->stats.hp);
+   if(op->stats.maxhp!=op2->stats.maxhp)
+     save_long(buf,variable_const[V_MAXHP],op->stats.maxhp);
+   if(op->stats.sp!=op2->stats.sp)
+     save_long(buf,variable_const[V_SP],op->stats.sp);
+   if(op->stats.maxsp!=op2->stats.maxsp)
+     save_long(buf,variable_const[V_MAXSP],op->stats.maxsp);
+   if(op->stats.grace!=op2->stats.grace)
+     save_long(buf,variable_const[V_GRACE],op->stats.grace);
+   if(op->stats.maxgrace!=op2->stats.maxgrace)
+     save_long(buf,variable_const[V_MAXGRACE],op->stats.maxgrace);
+   if(op->stats.exp!=op2->stats.exp)
+     save_long(buf,variable_const[V_EXP],op->stats.exp);
+   if(op->expmul!=op2->expmul) 
+     save_double(buf,variable_const[V_EXPMUL],op->expmul);
+   if(op->stats.food!=op2->stats.food)
+     save_long(buf,variable_const[V_FOOD],op->stats.food);
+   if(op->stats.dam!=op2->stats.dam)
+     save_long(buf,variable_const[V_DAM],op->stats.dam);
+   if(op->stats.luck!=op2->stats.luck)
+     save_long(buf,variable_const[V_LUCK],op->stats.luck);
+   if(op->stats.wc!=op2->stats.wc)
+     save_long(buf,variable_const[V_WC],op->stats.wc);
+   if(op->stats.ac!=op2->stats.ac)
+     save_long(buf,variable_const[V_AC],op->stats.ac);
+   if(op->armour!=op2->armour)
+     save_long(buf,variable_const[V_ARMOUR],op->armour);
+   if(op->x!=op2->x) 
+     save_long(buf,variable_const[V_X],op->x);
+   if(op->y!=op2->y)
+     save_long(buf,variable_const[V_Y],op->y);
+   if(op->speed!=op2->speed) {
+     sprintf(buf2,"speed %f\n",op->speed);
+     strcat(buf,buf2);
+   }
+   if(op->speed > 0 && op->speed_left!=op2->speed_left) {
+     sprintf(buf2,"speed_left %f\n",op->speed_left);
+     strcat(buf,buf2);
+   }
+   if(op->move_status != op2->move_status)
+     save_long(buf,variable_const[V_MOVE_STATUS],op->move_status);
+   if(op->move_type != op2->move_type)
+     save_long(buf,variable_const[V_ATT_MOVE],op->move_type);
+   if(op->nrof!=op2->nrof)
+     save_long(buf,variable_const[V_NROF],op->nrof);
+   if(op->level!=op2->level)
+     save_long(buf,variable_const[V_LEVEL],op->level);
+   if(op->direction!=op2->direction)
+     save_long(buf,variable_const[V_DIRECTION],op->direction);
+   if(op->type!=op2->type)
+     save_long(buf,variable_const[V_TYPE],op->type);
+   if(op->immune!=op2->immune)
+     save_long(buf,variable_const[V_IMMUNE],op->immune);
+   if(op->protected!=op2->protected)
+     save_long(buf,variable_const[V_PROTECTED],op->protected);
+   if(op->attacktype!=op2->attacktype)
+     save_long(buf,variable_const[V_ATTACKTYPE],op->attacktype);
+   if(op->vulnerable!=op2->vulnerable)
+     save_long(buf,variable_const[V_VULNERABLE],op->vulnerable);
+   if(op->path_attuned!=op2->path_attuned)
+     save_long(buf,variable_const[V_PATH_ATTUNED],op->path_attuned);
+   if(op->path_repelled!=op2->path_repelled)
+     save_long(buf,variable_const[V_PATH_REPELLED],op->path_repelled);
+   if(op->path_denied!=op2->path_denied)
+     save_long(buf,variable_const[V_PATH_DENIED],op->path_denied);
+   if(op->material!=op2->material)
+     save_long(buf,variable_const[V_MATERIAL],op->material);
+   if(op->value!=op2->value)
+     save_long(buf,variable_const[V_VALUE],op->value);
+   if(op->carrying!=op2->carrying)
+     save_long(buf,variable_const[V_CARRYING],op->carrying);
+   if(op->weight!=op2->weight)
+     save_long(buf,variable_const[V_WEIGHT],op->weight);
+   if(op->invisible!=op2->invisible)
+     save_long(buf,variable_const[V_INVISIBLE],op->invisible);
+   if(op->state!=op2->state)
+     save_long(buf,variable_const[V_STATE],op->state);
+   if(op->magic!=op2->magic)
+     save_long(buf,variable_const[V_MAGIC],op->magic);
+   if(op->last_heal!=op2->last_heal)
+     save_long(buf,variable_const[V_LAST_HEAL],op->last_heal);
+   if(op->last_sp!=op2->last_sp)
+     save_long(buf,variable_const[V_LAST_SP],op->last_sp);
+   if(op->last_grace!=op2->last_grace)
+     save_long(buf,variable_const[V_LAST_GRACE],op->last_grace);
+   if(op->last_eat!=op2->last_eat)
+     save_long(buf,variable_const[V_LAST_EAT],op->last_eat);
+   if(QUERY_FLAG(op,FLAG_IS_LINKED) && (tmp = get_button_value(op)))
+     save_long(buf,variable_const[V_CONNECTED],tmp);
+   if(op->glow_radius!=op2->glow_radius) 
+     save_long(buf,variable_const[V_GLOW_RADIUS],op->glow_radius);
+   if (op->randomitems!=op2->randomitems) {
+     sprintf(buf2,"randomitems %s\n",(op->randomitems?op->randomitems->name:"none"));
+     strcat(buf,buf2);
+   }
+ #ifdef NPC_PROG
+   if(op->npc_status!=op2->npc_status)
+     save_long(buf,variable_const[V_NPC_STATUS],op->npc_status);
+   if(op->npc_program!=op2->npc_program)
+     save_long(buf,variable_const[V_NPC_PROGRAM],op->npc_program);
+ #endif
+ 
+ 
+ /* Eneq(@csd.uu.se): Handles run_away and pick_up */
+   if(op->run_away!=op2->run_away)
+     save_long(buf,variable_const[V_RUN_AWAY],op->run_away);
+   if(op->pick_up!=op2->pick_up)
+     save_long(buf,variable_const[V_PICK_UP],op->pick_up);
+   if(op->weight_limit!=op2->weight_limit)
+     save_long(buf,variable_const[V_CONTAINER],op->weight_limit);
+ 
+ 
+ /* Vick (@bern.docs.uu.se) @921107 -> Handle 'will_apply' &
+    'random_movement.*/
+ 
+   if (op->will_apply!=op2->will_apply)
+     save_long(buf,variable_const[V_WILL_APPLY],op->will_apply);
+ 
+ /* Mol(@meryl.csd.uu.se) 921108  Handle can_apply */
+   if (op->can_apply!=op2->can_apply)
+     save_long(buf,variable_const[V_CAN_APPLY],op->can_apply);
+ 
+   for (tmp=0; tmp <= NUM_FLAGS; tmp++) {
+     if ((flag_links[tmp][0]!=-1) && (QUERY_FLAG(op, flag_links[tmp][0]) != 
+ 	QUERY_FLAG(op2, flag_links[tmp][0]))) {
+ 	    if (flag_links[tmp][0]==FLAG_SLOW_MOVE) {
+ 		sprintf(buf2,"%s %f\n",variable_const[V_SLOW_MOVE],SLOW_PENALTY(op));
+ 		strcat(buf,buf2);
+ 	    }
+ 	    else 
+ 	        BUFADD(QUERY_FLAG(op, flag_links[tmp][0]), flag_links[tmp][1]);
+ 	}
+   }
+   if(buf[0]=='\0')
+     return NULL;
+   return buf;
+ }
+ 
+ /*
+  * Dumps all variables in an object to a file.
+  * If bit 0 of flag is set, unpaid objects will be saved.  As of now,
+  * the only place this is not set is when saving the player.
+  * If bit 1 of flag is set, don't remove the object after save.  As of now,
+  * all of the callers are setting this.
+  */
+ 
+ void save_object(FILE *fp,object *op, int flag) {
+     archetype *at;
+     char *cp;
+     object *tmp,*old;
+ 
+     /* Even if the object does have an owner, it would seem that we should
+      * still save it.
+      */
+     if(op->owner!=NULL || fp == NULL)
+ 	return;
+ 
+     /* If it is unpaid and we don't want to save those, just return. */
+     if(!(flag&1)&&(QUERY_FLAG(op, FLAG_UNPAID))) {
+ 	return;
+     }
+ 
+     if((at=op->arch)==NULL) at=empty_archetype;
+     fprintf(fp,"arch %s\n",at->name);
+ 
+     if((cp=get_ob_diff(op,&at->clone))!=NULL)
+ 	fputs(cp,fp);	/* We really should do some status checking on this */
+ 
+     /* Eneq(@csd.uu.se): Added this to allow containers being saved with contents*/
+ 
+     old=NULL;
+ 
+     if (flag & 2 )
+ 	for(tmp=op->inv;tmp!=NULL;tmp=tmp->below)
+ 	    save_object(fp,tmp,flag);
+ 
+     /* Slightly different logic because tmp/op will be removed by
+      * the save_object we call.  So we just keep looking at op->inv
+      * until there is nothing left.  In theory, the variable old
+      * should not be needed, as recursive loops shouldn't happen.
+      */
+     else while ((tmp=op->inv)!=NULL) {
+ 	if(old==tmp) {
+ 	    LOG(llevError,"Recursive loop in inventory\n");
+ 	    break;
+ 	}
+ 	save_object(fp,tmp,flag); 
+ 	old=tmp;
+     }
+    
+     if (!(flag&2)) {
+ 	remove_ob(op);
+ 	free_object (op);
+     }
+ 
+     fprintf(fp,"end\n");
+ }
+ 
+ #ifndef NEW_LOAD 
+ 
+ /*
+  * Searches through all possible variables to find any that matches
+  * the given string.  An index to the variable_const[] array is returned,
+  * or -1 on failure.
+  */
+ 
+ int get_variable(char *name) {
+   int i;
+   char *tmp=find_string(name);
+   for(i=0;i<NR_OF_VARIABLES;i++)
+     if(variables[i]==tmp)
+       return i;
+   return -1;
+ }
+ /*
+  * set_variable() expects buf to be a line with two arguments, the first
+  * being a variable and the second being the value (which can be anything from
+  * an integer to a string). 
+  * The object given will have the given variable modified.
+  *
+  * -1 will be returned if there is no such variable
+  * 0 will be returned if the variable is to be ignored
+  * 1 will be returned if the variable was "anim"
+  * 2 will be returned if the variable was "end"
+  * 3 will be returned if the variable was "Inventory"
+  * 4 will be returned if the variable was "More"
+  * 5 will be returned if the variable was "msg"
+  * 6 will be returned if the variable was "endmsg"
+  * otherwise 0 will be returned
+  */
+ 
+ int set_variable(object *op,char *buf) {
+   char *vbp;
+   int value,tmp,var;
+ 
+   if((vbp=strchr(buf,'\n'))!=NULL) /* Change newline into end of string */
+     *vbp='\0';
+   else
+     LOG(llevDebug, "Line too long.\n");
+   if((vbp=strchr(buf,' '))==NULL) /* No argument to the variable */
+     value=0,vbp=NULL;
+   else {
+     *vbp='\0',vbp++;
+     value=atol(vbp);
+   }
+   switch(var=get_variable(buf)) {
+   case V_ARCH:
+     op->arch=find_archetype(vbp);
+     if(op->arch!=NULL)
+       copy_object(&op->arch->clone,op);
+     break;
+   case V_OTHER_ARCH:
+     op->other_arch=find_archetype(vbp);
+     break;
+   case V_RACE:
+     if(op->race!=NULL)
+       free_string(op->race);
+     op->race=add_string(vbp);
+     break;
+   case V_SLAYING:
+     if(op->slaying!=NULL)
+       free_string(op->slaying);
+     op->slaying=add_string(vbp);
+     break;
+   case V_MSG:
+     return 5;
+   case V_MSGEND:
+     return 6;
+   case V_INVENTORY:
+     return 3;
+   case V_MORE:
+     return 4;
+   case V_ANIM:
+     if(op->arch==NULL) {
+       LOG(llevError,"Got animation in object without archetype:\n");
+       return 0;
+     }
+     SET_FLAG(op,FLAG_ANIMATE);
+     return 1;
+   case V_END:
+     return 2;
+   case V_OBJECT:
+     if(vbp==NULL) {
+       LOG(llevError,"Object lacks name.\n");
+       return 0;
+     }
+     if(op->arch!=NULL)
+       op->arch->name=add_string(vbp);
+     op->name=add_string(vbp);
+     break;
+   case V_NAME:
+     if(*vbp=='\0') {
+       LOG(llevError,"name without name\n");
+       break;
+     }
+     if(op->name!=NULL)
+       free_string(op->name);
+     op->name=add_string(vbp);
+     break;
+   case V_TITLE:
+     if(*vbp=='\0') {
+       LOG(llevError, "title without name\n");
+       break;
+     }
+     if(op->title!=NULL)
+       free_string(op->title);
+     op->title = add_string(vbp);
+     break;
+   case V_SPEED:
+     sscanf(vbp,"%f",&op->speed);
+     if (op->speed<0)
+       op->speed_left=op->speed_left-RANDOM()%100/100.0;
+     update_ob_speed(op);
+     break;
+   case V_SPEED_LEFT:
+     sscanf(vbp,"%f",&op->speed_left);
+     break;
+   case V_SLOW_MOVE:
+     {
+       float f;
+       sscanf(vbp,"%f",&f);
+       SET_SLOW_PENALTY(op,f);
+       SET_FLAG(op,FLAG_SLOW_MOVE);
+     }
+     break;
+ /* Eneq(@csd.uu.se): Added handleof archetype-field anim_speed */
+ 
+   case V_ANIM_SPEED:
+     op->anim_speed = (unsigned char) value;
+     break;
+ /* kholland @ sunlab.cit.cornell.edu added move_type and status */
+   case V_ATT_MOVE:
+     op->move_type = (unsigned short) value;
+     break;
+   case V_MOVE_STATUS:
+     op->move_status = (signed long) value;
+     break;
+ /*
+  * Eneq(@csd.uu.se): Added handle of container <no> where no is containers
+  * weight limit, and no_drop which makes an item undroppable
+  */
+   case V_CONTAINER:
+     op->weight_limit=(signed long) value;
+     break;
+   case V_FACE:
+     op->face = &new_faces[FindFace(vbp,0)];
+     break;
+   case V_STR:
+     op->stats.Str=(signed char) value;
+     break;
+   case V_DEX:
+     op->stats.Dex=(signed char) value;
+     break;
+   case V_CON:
+     op->stats.Con=(signed char) value;
+     break;
+   case V_WIS:
+     op->stats.Wis=(signed char) value;
+     break;
+   case V_POW:
+     op->stats.Pow=(signed char) value;
+     break;
+   case V_CHA:
+     op->stats.Cha=(signed char) value;
+     break;
+   case V_INT:
+     op->stats.Int=(signed char) value;
+     break;
+   case V_HP:
+     op->stats.hp=(signed short) value;
+     break;
+   case V_MAXHP:
+     op->stats.maxhp=(signed short) value;
+     break;
+   case V_SP:
+     op->stats.sp=(signed short) value;
+     break;
+   case V_MAXSP:
+     op->stats.maxsp=(signed short) value;
+     break;
+   case V_GRACE:
+     op->stats.grace=(signed short) value;
+     break;
+   case V_MAXGRACE:
+     op->stats.maxgrace=(signed short) value;
+     break;
+   case V_EXP:
+     op->stats.exp=(signed long) value;
+     break;
+   case V_EXPMUL:
+     sscanf(vbp,"%lf",&(op->expmul));
+     break;
+   case V_FOOD:
+     op->stats.food=(sint16) value;
+     break;
+   case V_DAM:
+     op->stats.dam=(sint16) value;
+     break;
+   case V_LUCK:
+     op->stats.luck=(signed char) value;
+     break;
+   case V_WC:
+     op->stats.wc=(signed char) value;
+     break;
+   case V_AC:
+     op->stats.ac=(signed char) value;
+     break;
+   case V_ARMOUR:
+     op->armour=(signed char) value;
+     break;
+   case V_X:
+     op->x=(signed short) value,
+     op->ox=(signed short) value;
+     break;
+   case V_Y:
+     op->y=(signed short) value,
+     op->oy=(signed short) value;
+     break;
+   case V_NROF:
+     op->nrof=(unsigned long) value;
+     break;
+   case V_LEVEL:
+     op->level=(signed char) value;
+     break;
+   case V_DIRECTION:
+     op->direction=(signed char) value;
+     break;
+   case V_TYPE:
+     op->type=(unsigned char) value;
+     break;
+   case V_IMMUNE:
+     op->immune=(unsigned int) value;
+     break;
+   case V_PROTECTED:
+     op->protected=(unsigned int) value;
+     break;
+   case V_ATTACKTYPE:
+     op->attacktype=(unsigned int) value;
+     break;
+   case V_VULNERABLE:
+     op->vulnerable=(unsigned int) value;
+     break;
+   case V_PATH_ATTUNED:
+     op->path_attuned=(uint32) value;
+     break;
+   case V_PATH_REPELLED:
+     op->path_repelled=(uint32) value;
+     break;
+   case V_PATH_DENIED:
+     op->path_denied=(uint32) value;
+     break;
+   case V_MATERIAL:
+     op->material=(uint16) value;
+     break;
+   case V_VALUE:
+     op->value=(signed long) value;
+     break;
+   case V_CARRYING:
+     op->carrying=(signed long) value;
+     break;
+   case V_WEIGHT:
+     op->weight=(signed long) value;
+     break;
+   case V_INVISIBLE:
+     op->invisible=(signed short) value;
+     break;
+   case V_MAGIC:
+     op->magic=(unsigned char) value;
+     break;
+   case V_STATE:
+     op->state=(unsigned char) value;
+     break;
+   case V_LAST_HEAL:
+     op->last_heal=(signed short) value;
+     break;
+   case V_LAST_SP:
+     op->last_sp=(signed short) value;
+     break;
+   case V_LAST_GRACE:
+     op->last_grace=(signed short) value;
+     break;
+   case V_LAST_EAT:
+     op->last_eat=(signed short) value;
+     break;
+   case V_CONNECTED:
+     add_button_link(op, op->map, value);
+     break;
+ #ifdef NPC_PROG
+   case V_NPC_STATUS:
+     op->npc_status=(unsigned short) value;
+     break;
+   case V_NPC_PROGRAM:
+     op->npc_program=(unsigned short) value;
+     break;
+ #endif
+ 
+   case V_EDITABLE:
+     op->arch->editable = value;
+     break;
+ 
+ /* Eneq(@csd.uu.se): Handle PICK_UP */
+ 
+   case V_PICK_UP:
+     op->pick_up=(unsigned char) value;
+     break;
+ 
+ /* Eneq(@csd.uu.se): Handle RUN_AWAY, (CAN_)PASS_THRU. */
+ 
+   case V_RUN_AWAY:
+     op->run_away = (unsigned short) value;
+     break;
+ 
+ /* Vick's (vick@bern.docs.uu.se) patch 921107 : will_apply, which
+    enables a monster to apply things on the ground. */
+ 
+   case V_WILL_APPLY:
+     op->will_apply = (unsigned char) value;
+     break;
+ 
+   case V_GLOW_RADIUS:
+     op->glow_radius = (signed short) value;
+     break;
+ 
+ /* Note: With the new FLAG value method, most all of these bits are
+  * set in the default area.  The only ones not set there are
+  * special cases (those needing to check the object, print debugging
+  * messages, or SET/CLEAR multiple flags.
+  */
+ 
+   case V_WIZ:
+     if (value) {
+ 	SET_FLAG(op, FLAG_WIZ);
+ 	SET_FLAG(op, FLAG_WAS_WIZ);
+ 	SET_FLAG(op, FLAG_WIZPASS);
+     }
+     else {
+ 	CLEAR_FLAG(op, FLAG_WIZ);
+ 	CLEAR_FLAG(op, FLAG_WIZPASS);
+     }
+     break;
+ 
+ /* Mol(@csd.docs.uu.se) patch 921108 : can_apply, is similair to will_apply,
+    but applies thing it has picked up. */
+ 
+   case V_CAN_APPLY:
+     op->can_apply = (unsigned char) value;
+     break;
+ 
+   case V_FRIENDLY:
+     if(value) {
+       SET_FLAG(op,FLAG_FRIENDLY);
+       if (op->type != PLAYER) {
+         LOG(llevDebug, "Adding friendly object %s.\n",op->name);
+         add_friendly_object(op);
+       }
+     }
+     else
+       CLEAR_FLAG(op,FLAG_FRIENDLY);
+     break;
+ 
+   case V_IDENTIFIED:
+     if(value) {
+       SET_FLAG(op,FLAG_IDENTIFIED);
+       CLEAR_FLAG(op, FLAG_KNOWN_MAGICAL);
+     }
+     else
+       CLEAR_FLAG(op,FLAG_IDENTIFIED);
+     break;
+ 
+   case V_WAS_WIZ:
+     if(value)
+       SET_FLAG(op,FLAG_WAS_WIZ);
+     else
+       CLEAR_FLAG(op,FLAG_WAS_WIZ);
+     break;
+   case V_RANDOMITEMS:
+     op->randomitems=find_treasurelist(vbp);
+     break;
+     
+ 
+  /* In the default statement, it will handle all cases above.
+   * First search through the flag_links, to match corresponding
+   * variables.  If it doesn't find anything, then print the error messages.
+   */
+   default:
+     for (tmp=0; tmp<=NUM_FLAGS; tmp++) {
+ 	if (flag_links[tmp][1]==var) {
+ 	    if (value) SET_FLAG(op, flag_links[tmp][0]);
+ 	    else CLEAR_FLAG(op, flag_links[tmp][0]);
+ 	    return 0;
+ 	}
+     }
+     sprintf(errmsg,"Warning, unknown (or oldfashioned) variable: %s",buf);
+     return -1;
+   }
+   return 0;
+ }
+ 
+ /*
+  * Loads an object from the given file-pointer.
+  * Variables will be read and parsed and patched into the object
+  * until the string "end" is reached, or the end of the file.
+  * If EOF is reached, it returnes false, otherwise true.
+  */
+ 
+ int load_object(FILE *fp, object *op, int a) {
+   char buf[MAX_BUF];
+   char msgbuf[HUGE_BUF];
+   Fontindex faces[MAX_ANIMATIONS];
+   int position=1; /* 1 = standalone, 2 = inventory, 3 = head/tail link */
+   int anim_start=0,msg_start=0;
+   object *tmp;
+ 
+   buf[MAX_BUF - 1] = '\0';
+   while(fgets(buf,sizeof(buf),fp)!=NULL) {
+     if(*buf=='#')
+       continue;
+     if(anim_start) {
+       if(!strncmp("mina",buf,4)) {
+ 	op->arch->animation_id=add_animation(op->arch->name, anim_start-1, faces);
+ 	anim_start=0;
+       } else {
+ 	  faces[anim_start - 1] = FindFace(buf,0);
+ 	  anim_start++;
+       }
+       continue;
+     }
+     if(msg_start&&strncmp(buf,"endmsg",6)) {
+       strcat(msgbuf,buf);
+       continue;
+     }
+     /* found an arch in the object.  Must be part of the
+      * objects inventory.
+      */
+     if(!strncmp(buf,"arch ",5)&&op->arch!=NULL) {
+         object *otmp;
+ 
+         tmp=get_object();
+ 	set_variable(tmp, buf);
+         load_object(fp, tmp,0);
+         if (op->inv!=NULL) {
+             for (otmp=op->inv; otmp->below!=NULL; otmp=otmp->below);
+             otmp->below=tmp;
+         }
+ 	else op->inv=tmp;
+         return load_object (fp, op,0);
+     }
+     switch(set_variable(op,buf)) {
+     case -1:
+       LOG(llevError,"%s\n",errmsg);
+       break;
+     case 1:
+       anim_start=1;
+       break;
+     case 2:
+       return position;
+     case 3:
+       position=2;
+       break;
+     case 4:
+       position=3;
+       break;
+     case 5:
+       msg_start=1;
+       msgbuf[0]='\0';
+       break;
+     case 6:
+       msg_start=0;
+       op->msg=add_string(msgbuf);
+ 	/* Only reason to worry about this is if we might be in danger
+ 	 * of going beyond the limits of the buffer.
+ 	 */
+       if (strlen(op->msg) > (HUGE_BUF/2))
+ 	LOG(llevDebug, "\n\tWarning message length > %d (max allowed=%d): %d\n>%.80s<\n",
+ 	    HUGE_BUF/2, HUGE_BUF,
+ 	    strlen(op->msg),op->msg);
+       break;
+     }
+   }
+   return 0;
+ }
+ 
+ 
+ /*
+  * Loads an object from the given file-pointer.
+  * Variables will be read and parsed and patched into the object
+  * until the string "end" is reached, or the end of the file.
+  * If EOF is reached, it returnes false, otherwise true.
+  */
+ 
+ enum LoadState { unknown, arch, anim, message };
+ 
+ object *LoadObject (FILE *fp, char *inbuf) {
+     char buf[256];
+     char msgbuf[HUGE_BUF];
+     Fontindex faces[MAX_ANIMATIONS];
+     int anim_start = 0;
+     object *op = NULL;
+     enum LoadState state = unknown;
+     
+    if (inbuf!=NULL) {
+      if (strncmp("arch", inbuf, 4))
+ 	LOG (llevError, "parse error in inbuf: %s\n (expecting arch)", inbuf);
+       else {
+ 	state = arch;
+ 	op = get_object();
+ 	set_variable (op, inbuf);
+       }
+    }
+ 
+     while(fgets(buf,sizeof(buf),fp)!=NULL) {
+ 	if(*buf=='#')
+ 	    continue;
+ 
+ 	switch (state) {
+ 	  case unknown:
+ 	    if (strncmp ("arch", buf, 4))
+ 		LOG (llevError, "parse error in: %s\n (expecting arch)", buf);
+ 	    else {
+ 		state = arch;
+ 		op = get_object();
+ 		set_variable (op, buf);
+ 	    }
+ 	    break;
+ 
+ 	  case arch:
+ 	    if(!strncmp (buf, "arch ", 5)) {
+ 		object *tmp;
+ 		tmp = LoadObject(fp,buf);
+ 		/* If we don't have an arch or name, chances are the object
+ 		 * is one that has been removed or isn't available.  Just
+ 		 * drop it then (can't really dump it - no information
+ 		 * to show.)
+ 		 */
+ 		if (!tmp->arch && !tmp->name) {
+ 		    LOG(llevDebug,"Dropping null object.\n");
+ 		    free_object(tmp);
+ 		}
+ 		else
+ 		    (void) insert_ob_in_ob (tmp, op);
+ 		break;
+ 	    }
+ 
+ 	    switch(set_variable (op, buf)) {
+ 	      case -1:
+ 		LOG(llevError,"%s\n",errmsg);
+ 		break;
+ 		
+ 	      case 0:
+ 		break;
+ 
+ 	      case 1:
+ 		state = anim;
+ 		anim_start = 0;
+ 		break;
+ 
+ 	      case 2:
+ 		return op;
+ 
+ 	      case 5:
+ 		state = message;
+ 		msgbuf[0] = '\0';
+ 		break;
+ 
+ 	      default:
+ 		LOG(llevError,"LoadObject()\n");
+ 		break;
+ 	    }       
+ 	    break;
+ 
+ 	  case anim:
+ 	    if(!strncmp ("mina", buf, 4)) {
+ 		op->arch->animation_id=add_animation(op->arch->name, anim_start, faces);
+ 		state = arch;
+ 		break;
+ 	    }
+ 	    faces[anim_start++] = FindFace(buf,0);
+ 	    break;
+ 
+ 	  case message:
+ 	    if(!strncmp (buf, "endmsg", 6)) {
+ 		op->msg = add_string (msgbuf);
+ 		state = arch;
+ 		break;
+ 	    }
+ 	    strcat(msgbuf,buf);
+ 	}
+     }
+     if (op)
+ 	free_object (op);
+ 
+     return NULL;
+ }
+ 
+ #endif
*** crossfire-0.94.0//doc/Imakefile	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/doc/Imakefile	Sun Apr 12 21:26:09 1998
***************
*** 1,6 ****
  /*   CrossFire, A Multiplayer game for X-windows
   *
!  *   $Id: Imakefile,v 1.4 1998/01/05 10:32:02 master Exp master $
   *
   *   Copyright (C) 1992 Frank Tore Johansen
   *
--- 1,6 ----
  /*   CrossFire, A Multiplayer game for X-windows
   *
!  *   $Id: Imakefile,v 1.4 1998/01/05 10:32:02 master Exp $
   *
   *   Copyright (C) 1992 Frank Tore Johansen
   *
*** crossfire-0.94.0//doc/crossfire.man	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/doc/crossfire.man	Sun Apr 12 21:26:21 1998
***************
*** 1,4 ****
! .\"$Id: crossfire.man,v 1.7 1998/01/05 10:32:52 master Exp master $
  .TH crossfire 0.93.1 "January 5, 1997"
  .SH NAME
  CrossFire - multiplayer adventure and arcade game for X-windows
--- 1,4 ----
! .\"$Id: crossfire.man,v 1.7 1998/01/05 10:32:52 master Exp $
  .TH crossfire 0.93.1 "January 5, 1997"
  .SH NAME
  CrossFire - multiplayer adventure and arcade game for X-windows
*** crossfire-0.94.0//server/apply.c	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/server/apply.c	Sun Apr 12 21:37:11 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_apply_c =
!  *   "$Id: apply.c,v 1.59 1997/11/11 11:24:20 master Exp $";
   */
  /*
      CrossFire, A Multiplayer game for X-windows
--- 1,6 ----
  /*
   * static char *rcsid_apply_c =
!  *   "$Id: apply.c,v 1.60 1998/04/12 21:32:19 master Exp master $";
   */
  /*
      CrossFire, A Multiplayer game for X-windows
***************
*** 1185,1193 ****
  /* apply returns 0 if it wasn't possible to apply that object */
  /* op is the object that is causing object to be applied, tmp is the object
   * being applied.
   */
  
! int apply(object *op, object *tmp) {
    char buf[MAX_BUF];
    int inven;
  
--- 1185,1195 ----
  /* apply returns 0 if it wasn't possible to apply that object */
  /* op is the object that is causing object to be applied, tmp is the object
   * being applied.
+  * aflag is special (always apply/unapply) flags.  Nothing is done with
+  * them in this function - they are passed to apply_special
   */
  
! int apply(object *op, object *tmp, int aflag) {
    char buf[MAX_BUF];
    int inven;
  
***************
*** 1738,1744 ****
      break;
    }
    case WAND:
!     if(apply_special(op,tmp))
        return 1;
      if(op->type==PLAYER) {
        if(QUERY_FLAG(tmp, FLAG_APPLIED)) {
--- 1740,1746 ----
      break;
    }
    case WAND:
!     if(apply_special(op,tmp,aflag))
        return 1;
      if(op->type==PLAYER) {
        if(QUERY_FLAG(tmp, FLAG_APPLIED)) {
***************
*** 1758,1764 ****
      }
      return 1;
    case ROD:
!     if(apply_special(op,tmp))
        return 1;
      if(op->type==PLAYER) {
        if(QUERY_FLAG(tmp, FLAG_APPLIED)) {
--- 1760,1766 ----
      }
      return 1;
    case ROD:
!     if(apply_special(op,tmp,aflag))
        return 1;
      if(op->type==PLAYER) {
        if(QUERY_FLAG(tmp, FLAG_APPLIED)) {
***************
*** 1778,1784 ****
      }
      return 1;
    case HORN:
!     if(apply_special(op,tmp))
        return 1;
      if(op->type==PLAYER) {
        if(QUERY_FLAG(tmp, FLAG_APPLIED)) {
--- 1780,1786 ----
      }
      return 1;
    case HORN:
!     if(apply_special(op,tmp,aflag))
        return 1;
      if(op->type==PLAYER) {
        if(QUERY_FLAG(tmp, FLAG_APPLIED)) {
***************
*** 1798,1804 ****
      }
      return 1;
    case BOW:
!     if(apply_special(op,tmp))
        return 0;
      if(QUERY_FLAG(tmp, FLAG_APPLIED)) {
        new_draw_info_format(NDI_UNIQUE, 0, op,
--- 1800,1806 ----
      }
      return 1;
    case BOW:
!     if(apply_special(op,tmp,aflag))
        return 0;
      if(QUERY_FLAG(tmp, FLAG_APPLIED)) {
        new_draw_info_format(NDI_UNIQUE, 0, op,
***************
*** 1812,1818 ****
      return 1;
  #ifdef ALLOW_SKILLS
    case SKILL:   /* allows skill tools  to be used -b.t */
!     if(apply_special(op,tmp))
        return 0;
      if((!tmp->invisible||op->type!=PLAYER)&&QUERY_FLAG(tmp, FLAG_APPLIED)) {
          SET_FLAG(op, FLAG_READY_SKILL);
--- 1814,1820 ----
      return 1;
  #ifdef ALLOW_SKILLS
    case SKILL:   /* allows skill tools  to be used -b.t */
!     if(apply_special(op,tmp,aflag))
        return 0;
      if((!tmp->invisible||op->type!=PLAYER)&&QUERY_FLAG(tmp, FLAG_APPLIED)) {
          SET_FLAG(op, FLAG_READY_SKILL);
***************
*** 1844,1850 ****
    case CLOAK:
  /* Mol(mol@meryl.csd.uu.se) compressed return & apply_s into one statement */
  /* Frank: If done this way, a ! must be prepended */
!     return !apply_special(op,tmp);
    case DRINK:
    case FOOD:
    case FLESH:
--- 1846,1852 ----
    case CLOAK:
  /* Mol(mol@meryl.csd.uu.se) compressed return & apply_s into one statement */
  /* Frank: If done this way, a ! must be prepended */
!     return !apply_special(op,tmp,aflag);
    case DRINK:
    case FOOD:
    case FLESH:
***************
*** 2038,2049 ****
     * instead of whats on the ground.
     */
    if (op->container!=NULL) {
!     for(tmp=op->container->inv;tmp!=NULL&&!apply(op,tmp);tmp=tmp->below);
    } else
!     for(tmp=op->below;tmp!=NULL&&!apply(op,tmp);tmp=tmp->below);
  }
  
! int apply_special(object *who,object *op) { /* wear/wield */
    object *tmp;
    char buf[MAX_BUF];
    int i;
--- 2040,2056 ----
     * instead of whats on the ground.
     */
    if (op->container!=NULL) {
!     for(tmp=op->container->inv;tmp!=NULL&&!apply(op,tmp,0);tmp=tmp->below);
    } else
!     for(tmp=op->below;tmp!=NULL&&!apply(op,tmp,0);tmp=tmp->below);
  }
  
! /* who is the object using the object.
!  * op is the object they are using.
!  * aflags is special flags (0 - normal/toggel, 1=always apply, 2=always unapply
!  * (see define.h, AP_* values)
!  */
! int apply_special(object *who,object *op, int aflags) { /* wear/wield */
    object *tmp;
    char buf[MAX_BUF];
    int i;
***************
*** 2058,2063 ****
--- 2065,2072 ----
      return 1;
    }
    if(QUERY_FLAG(op,FLAG_APPLIED)) {
+     /* always apply, so no reason to unapply */
+     if (aflags == AP_APPLY) return 0;
      if (QUERY_FLAG(op, FLAG_CURSED) || QUERY_FLAG(op, FLAG_DAMNED))
      {
        new_draw_info_format(NDI_UNIQUE, 0, who,
***************
*** 2156,2161 ****
--- 2165,2171 ----
  
      return 0;
    }
+   if (aflags == AP_UNAPPLY) return 0;
    if (QUERY_FLAG(op, FLAG_UNPAID)) {
      new_draw_info(NDI_UNIQUE, 0,who, "You should pay for it first.\n");
      return 0;
***************
*** 2165,2171 ****
      if(tmp->type==op->type&&QUERY_FLAG(tmp, FLAG_APPLIED)&&tmp!=op)
        if(tmp->type==RING&&!i)
          i=1;
!       else if(apply_special(who,tmp))
          return 0;
    if(op->nrof > 1)
      tmp = get_split_ob(op,op->nrof - 1);
--- 2175,2181 ----
      if(tmp->type==op->type&&QUERY_FLAG(tmp, FLAG_APPLIED)&&tmp!=op)
        if(tmp->type==RING&&!i)
          i=1;
!       else if(apply_special(who,tmp,aflags))
          return 0;
    if(op->nrof > 1)
      tmp = get_split_ob(op,op->nrof - 1);
*** crossfire-0.94.0//server/attack.c	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/server/attack.c	Sun Apr 12 21:37:29 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_attack_c =
!  *   "$Id: attack.c,v 1.38 1998/02/08 01:58:51 master Exp master $";
   */
  /*
      CrossFire, A Multiplayer game for X-windows
--- 1,6 ----
  /*
   * static char *rcsid_attack_c =
!  *   "$Id: attack.c,v 1.39 1998/04/12 21:37:11 master Exp master $";
   */
  /*
      CrossFire, A Multiplayer game for X-windows
***************
*** 1562,1568 ****
          break;
        case POISON: /* poison drinks */
          if(QUERY_FLAG(victim,FLAG_ALIVE)&&!QUERY_FLAG(victim,FLAG_UNDEAD)
! 	  &&!(victim->immune&AT_POISON)) apply(victim,tmp);
          break;
        case CONTAINER: 
          /* spill_container(victim,RANDOM()%(hitter->stats.dam+1)); */
--- 1562,1568 ----
          break;
        case POISON: /* poison drinks */
          if(QUERY_FLAG(victim,FLAG_ALIVE)&&!QUERY_FLAG(victim,FLAG_UNDEAD)
! 	  &&!(victim->immune&AT_POISON)) apply(victim,tmp,0);
          break;
        case CONTAINER: 
          /* spill_container(victim,RANDOM()%(hitter->stats.dam+1)); */
*** crossfire-0.94.0//server/c_misc.c	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/server/c_misc.c	Sun Apr 12 21:37:29 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_c_misc_c =
!  *   "$Id: c_misc.c,v 1.19 1998/02/08 02:01:28 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_c_misc_c =
!  *   "$Id: c_misc.c,v 1.19 1998/02/08 02:01:28 master Exp $";
   */
  
  /*
*** crossfire-0.94.0//server/c_object.c	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/server/c_object.c	Mon Mar  9 05:02:38 1998
***************
*** 6,11 ****
--- 6,12 ----
  #include <global.h>
  #include <loader.h>
  #include <sproto.h>
+ #include <living.h>
  
  /*
   * Object id parsing functions
***************
*** 183,189 ****
      inv= find_first_inventory_item(op);
    }
    if(inv) {
!     if(!apply(op,inv)) {
        new_draw_info_format(NDI_UNIQUE, 0, op,
  	"I don't know how to apply the %s.",query_name(inv));
      }
--- 184,190 ----
      inv= find_first_inventory_item(op);
    }
    if(inv) {
!     if(!apply(op,inv,0)) {
        new_draw_info_format(NDI_UNIQUE, 0, op,
  	"I don't know how to apply the %s.",query_name(inv));
      }
***************
*** 199,207 ****
      return 0;
    }
    else {
!     object *inv=find_best_object_match(op, params);
      if (inv) {
! 	if(!apply(op,inv)) {
  	  new_draw_info_format(NDI_UNIQUE, 0, op,
  	    "I don't know how to apply the %s.",query_name(inv));
  	}
--- 200,222 ----
      return 0;
    }
    else {
!     int aflag=0;
!     object *inv;
! 
!     while (*params==' ') params++;
!     if (!strncmp(params,"-a ",3)) {
! 	aflag=AP_APPLY;
! 	params+=3;
!     }
!     if (!strncmp(params,"-u ",3)) {
! 	aflag=AP_UNAPPLY;
! 	params+=3;
!     }
!     while (*params==' ') params++;
! 
!     inv=find_best_object_match(op, params);
      if (inv) {
! 	if(!apply(op,inv,aflag)) {
  	  new_draw_info_format(NDI_UNIQUE, 0, op,
  	    "I don't know how to apply the %s.",query_name(inv));
  	}
***************
*** 217,222 ****
--- 232,271 ----
    return 0;
  }
  
+ /*
+  * Check if an item op can be put into a sack. If pl exists then tell
+  * a player the reason of failure.
+  * returns 1 if it will fit, 0 if it will not.  nrof is the number of
+  * objects (op) we want to put in.  We specify it separately instead of
+  * using op->nrof because often times, a player may have specified a
+  * certain number of objects to drop, so we can pass that number, and
+  * not need to use split_ob and stuff.
+  */
+ int sack_can_hold (object *pl, object *sack, object *op, int nrof) {
+     char buf[MAX_BUF];
+     buf[0] = 0;
+ 
+     if (! QUERY_FLAG (sack, FLAG_APPLIED))
+ 	sprintf (buf, "%s is not active.", query_name(sack));
+     if (sack == op)
+ 	sprintf (buf, "You can't put %s into itself.", query_name(sack));
+     if (sack->race && (sack->race != op->race || op->type == CONTAINER
+ 		       || (sack->stats.food && sack->stats.food != op->type)))
+ 	sprintf (buf, "You can put only %s into %s.", sack->race,
+ 		 query_name(sack));
+     if (op->type == SPECIAL_KEY && sack->slaying && op->slaying)
+ 	sprintf (buf, "You don't want put the key into %s.", query_name(sack));
+     if (sack->weight_limit && sack->carrying + (nrof ? nrof : 1) * 
+ 	op->weight * (100 - sack->stats.Str) / 100  > sack->weight_limit)
+ 	sprintf (buf, "That won't fit in %s!", query_name(sack));
+     if (buf[0]) {
+ 	if (pl)
+ 	    new_draw_info(NDI_UNIQUE, 0,pl, buf);
+ 	return 0;
+     }
+     return 1;
+ }
+ 
  /* Pick up commands follow */
  /* pl = player, op is the object to put tmp into, 
   * tmp is the object to pick up, nrof is the number to
***************
*** 226,231 ****
--- 275,281 ----
  {
      char buf[MAX_BUF];
      object *env=tmp->env;
+     uint32 weight;
  
      /* IF the player is flying & trying to take the item out of a container 
       * that is in his inventory, let him.  tmp->env points to the container 
***************
*** 257,262 ****
--- 307,323 ----
  	free_object(tmp);
  	return;
      }
+     /* Figure out how much weight this object will add to the player */
+     weight = tmp->weight;
+     if (nrof) weight *=nrof;
+     else if (tmp->nrof) weight *= tmp->nrof;
+     if (op->type == CONTAINER) weight = weight * (100 - op->stats.Str) / 100;
+     if ((pl->weight + pl->carrying +weight) > weight_limit[pl->stats.Str]) {
+ 	new_draw_info(NDI_UNIQUE, 0,pl,"That item is too heavy for you to pick up.");
+ 	return;
+     }
+ 	
+ 
  #ifndef REAL_WIZ
      if(QUERY_FLAG(pl, FLAG_WAS_WIZ))
  	SET_FLAG(tmp, FLAG_WAS_WIZ);
***************
*** 471,477 ****
      if(QUERY_FLAG(tmp, FLAG_APPLIED)) {
        int nrof = tmp->nrof, a;
        tmp->nrof = 0;
!       a = apply_special(op,tmp);
        tmp->nrof = nrof;
        if (a)
  	  return;
--- 532,538 ----
      if(QUERY_FLAG(tmp, FLAG_APPLIED)) {
        int nrof = tmp->nrof, a;
        tmp->nrof = 0;
!       a = apply_special(op,tmp,0);
        tmp->nrof = nrof;
        if (a)
  	  return;
***************
*** 543,549 ****
      if(QUERY_FLAG(tmp, FLAG_APPLIED)) {
        int nrof = tmp->nrof,a;
        tmp->nrof = 0;
!       a = apply_special (op, tmp);
        tmp->nrof = nrof;
        if (a)		/* can't unapply it */
  	  return;
--- 604,610 ----
      if(QUERY_FLAG(tmp, FLAG_APPLIED)) {
        int nrof = tmp->nrof,a;
        tmp->nrof = 0;
!       a = apply_special (op, tmp,0);
        tmp->nrof = nrof;
        if (a)		/* can't unapply it */
  	  return;
*** crossfire-0.94.0//server/c_wiz.c	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/server/c_wiz.c	Sun Apr 12 21:40:25 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_c_wiz_c =
!  *   "$Id: c_wiz.c,v 1.15 1998/02/08 02:08:36 master Exp master $";
   */
  /*
      CrossFire, A Multiplayer game for X-windows
--- 1,6 ----
  /*
   * static char *rcsid_c_wiz_c =
!  *   "$Id: c_wiz.c,v 1.16 1998/04/12 21:38:58 master Exp master $";
   */
  /*
      CrossFire, A Multiplayer game for X-windows
***************
*** 124,130 ****
    if ((op==NULL && !active_socket->wiz && ((first_socket!=NULL && first_socket->next!=NULL) || (first_player!=NULL))) ||
        (op!=NULL && !QUERY_FLAG(op,FLAG_WIZ) && ((first_socket!=NULL) || (first_player!=NULL && first_player->next!=NULL))))
      {
!       new_draw_info(NDI_UNIQUE,0,op,"Sorry, can't shutdown now.");
        return 1;
      }
    command_kick(NULL,NULL);
--- 124,130 ----
    if ((op==NULL && !active_socket->wiz && ((first_socket!=NULL && first_socket->next!=NULL) || (first_player!=NULL))) ||
        (op!=NULL && !QUERY_FLAG(op,FLAG_WIZ) && ((first_socket!=NULL) || (first_player!=NULL && first_player->next!=NULL))))
      {
!       new_draw_info(NDI_UNIQUE,0,op,"Sorry, you can't shutdown the server.");
        return 1;
      }
    command_kick(NULL,NULL);
***************
*** 139,166 ****
  
  int command_goto (object *op, char *params)
  {
!       char *name;
!       object *dummy;
  
!   if (!op)
!     return 0;
  
!   if(params == NULL) {
          new_draw_info(NDI_UNIQUE, 0,op,"Go to what level?");
          return 1;
        }
!   name = params;
!       dummy=get_object();
!       dummy->map = op->map;
!       EXIT_PATH(dummy) = add_string (name);
!       enter_exit(op,dummy);
!       free_object(dummy);
!       if(op->contr->loading == NULL) {
  	new_draw_info_format(NDI_UNIQUE, 0, op,
  	    "Difficulty: %d.",op->map->difficulty);
-       }
-       return 1;
      }
  
  /* is this function called from somewhere ? -Tero */
  int command_generate (object *op, char *params)
--- 139,168 ----
  
  int command_goto (object *op, char *params)
  {
!     char *name;
!     object *dummy;
  
!     if (!op)
! 	return 0;
  
!     if(params == NULL) {
          new_draw_info(NDI_UNIQUE, 0,op,"Go to what level?");
          return 1;
        }
!     name = params;
!     dummy=get_object();
!     dummy->map = op->map;
!     EXIT_PATH(dummy) = add_string (name);
!     dummy->name = add_string(name);
! 
!     enter_exit(op,dummy);
!     free_object(dummy);
!     if(op->contr->loading == NULL) {
  	new_draw_info_format(NDI_UNIQUE, 0, op,
  	    "Difficulty: %d.",op->map->difficulty);
      }
+     return 1;
+ }
  
  /* is this function called from somewhere ? -Tero */
  int command_generate (object *op, char *params)
*** crossfire-0.94.0//server/commands.c	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/server/commands.c	Sun Mar  1 09:33:51 1998
***************
*** 79,84 ****
--- 79,85 ----
    {"shout", command_shout,	0.0},
    {"show", command_show,	0.0},
    {"showinvicon", command_show_inv_icon, 0.0},
+   {"shutdown", command_shutdown, 0.0},
  #ifdef ALLOW_SKILLS
    {"skills", command_skills,	0.0},	/* shows player list of skills */
    {"use_skill", command_uskill, 1.0},
***************
*** 147,152 ****
--- 148,154 ----
    {"quit", command_quit,0.0},
    {"set", command_set,0.0},
    {"shout", command_shout,0.0},
+   {"shutdown", command_shutdown, 0.0},
    {"strings", command_strings,0.0},
    {"sync", command_sync,0.0},
    {"tell", command_tell,0.0},
*** crossfire-0.94.0//server/egoitem.c	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/server/egoitem.c	Sun Apr 12 21:41:11 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_egoitem_c =
!  *   "$Id: egoitem.c,v 1.4 1998/02/08 02:11:45 master Exp master $";
   */
   
  
--- 1,6 ----
  /*
   * static char *rcsid_egoitem_c =
!  *   "$Id: egoitem.c,v 1.4 1998/02/08 02:11:45 master Exp $";
   */
   
  
*** crossfire-0.94.0//server/ericserver.c	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/server/ericserver.c	Fri Mar 13 09:53:51 1998
***************
*** 28,33 ****
--- 28,34 ----
  #ifdef ERIC_SERVER
  #include <newclient.h>
  #include <newserver.h>
+ #include <living.h>
  
  /* This block is basically taken from socket.c - I assume if it works there,
   * it should work here.
***************
*** 173,179 ****
      if (getsockopt(cs_sockets[cnum].fd,SOL_SOCKET,SO_SNDBUF, (char*)&oldbufsize, &buflen)==-1)
  	oldbufsize=0;
      if (oldbufsize<bufsize) {
! #ifdef ESRV_DBEBUG
  	LOG(llevDebug, "Default buffer size was %d bytes, will reset it to %d\n", oldbufsize, bufsize);
  #endif
  	if(setsockopt(cs_sockets[cnum].fd,SOL_SOCKET,SO_SNDBUF, (char*)&bufsize, sizeof(&bufsize))) {
--- 174,180 ----
      if (getsockopt(cs_sockets[cnum].fd,SOL_SOCKET,SO_SNDBUF, (char*)&oldbufsize, &buflen)==-1)
  	oldbufsize=0;
      if (oldbufsize<bufsize) {
! #ifdef ESRV_DEBUG
  	LOG(llevDebug, "Default buffer size was %d bytes, will reset it to %d\n", oldbufsize, bufsize);
  #endif
  	if(setsockopt(cs_sockets[cnum].fd,SOL_SOCKET,SO_SNDBUF, (char*)&bufsize, sizeof(&bufsize))) {
***************
*** 495,502 ****
      }
  }
  
! void 
! esrv_play_sound(object *pl, int soundnum,  int x, int y)
  {
      int client_num,soundtype;
      SockList sl;
--- 496,502 ----
      }
  }
  
! void esrv_play_sound(object *pl, int soundnum,  int x, int y)
  {
      int client_num,soundtype;
      SockList sl;
***************
*** 901,907 ****
      long cid;
      fd_set tmp_read, tmp_exceptions;
      struct sockaddr_in addr;
!     intt addrlen=sizeof(struct sockaddr);
  
  /* Start at connection 1, being that 0 is the what listens on the port. */
      for(i=1;i<nconns;i++) {
--- 901,907 ----
      long cid;
      fd_set tmp_read, tmp_exceptions;
      struct sockaddr_in addr;
!     int addrlen=sizeof(struct sockaddr);
  
  /* Start at connection 1, being that 0 is the what listens on the port. */
      for(i=1;i<nconns;i++) {
***************
*** 1105,1111 ****
      AddIfFloat(pl->contr->last_speed, pl->speed, CS_STAT_SPEED);
      AddIfShort(pl->contr->last_stats.food, pl->stats.food, CS_STAT_FOOD);
      AddIfFloat(pl->contr->last_weapon_sp, pl->contr->weapon_sp, CS_STAT_WEAP_SP);
! 
      flags=0;
      if (pl->contr->fire_on) flags |=SF_FIREON;
      if (pl->contr->run_on) flags |= SF_RUNON;
--- 1105,1111 ----
      AddIfFloat(pl->contr->last_speed, pl->speed, CS_STAT_SPEED);
      AddIfShort(pl->contr->last_stats.food, pl->stats.food, CS_STAT_FOOD);
      AddIfFloat(pl->contr->last_weapon_sp, pl->contr->weapon_sp, CS_STAT_WEAP_SP);
!     AddIfInt(pl->contr->last_weight_limit, weight_limit[pl->stats.Str], CS_STAT_WEIGHT_LIM);
      flags=0;
      if (pl->contr->fire_on) flags |=SF_FIREON;
      if (pl->contr->run_on) flags |= SF_RUNON;
***************
*** 1472,1477 ****
--- 1472,1482 ----
  #endif
  	return;
      }
+     /* IF player is just joining the game, he isn't here yet, so the map
+      * can get swapped out.  If so, don't try to send them a map.  All will
+      * be OK once they really log in.
+      */
+     if (pl->map->in_memory!=MAP_IN_MEMORY) return;
      memset(&newmap, 0, sizeof(struct Map));
  
      if(pl->invisible & (pl->invisible < 50 ? 4 : 1)) {
***************
*** 1592,1596 ****
--- 1597,1604 ----
  void draw_client_map(object *pl) {} 
  void esrv_map_scroll(long client_id,int dx,int dy) {}
  void free_all_ericserver() {}
+ void esrv_ToggleSound(object *pl, int client_num) {}
+ void esrv_play_sound(object *pl, int soundnum,  int x, int y) {}
+ void HandleClient(int cnum){}
  #endif
  
*** crossfire-0.94.0//server/hiscore.c	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/server/hiscore.c	Sun Apr 12 21:44:51 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_hiscore_c =
!  *   "$Id: hiscore.c,v 1.16 1998/02/08 02:20:46 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_hiscore_c =
!  *   "$Id: hiscore.c,v 1.17 1998/04/12 21:44:29 master Exp master $";
   */
  
  /*
***************
*** 106,112 ****
    strncpy(sc.name,cp,BIG_NAME);
    sc.name[BIG_NAME - 1] = '\0';
  
!   if ((cp = spool(bp, "title")) == NULL)
      return NULL;
    strncpy(sc.title,cp,BIG_NAME);
    sc.title[BIG_NAME - 1] = '\0';
--- 106,112 ----
    strncpy(sc.name,cp,BIG_NAME);
    sc.name[BIG_NAME - 1] = '\0';
  
!   if ((cp = spool(NULL, "title")) == NULL)
      return NULL;
    strncpy(sc.title,cp,BIG_NAME);
    sc.title[BIG_NAME - 1] = '\0';
***************
*** 143,158 ****
      static char retbuf[MAX_BUF];
  
      if(!strncmp(sc->killer,"quit",MAX_NAME))
! 	sprintf(retbuf,"%3d %10ld %s quit the game on map %s [%d][%d][%d].",
!             sc->position,sc->exp,sc->name,sc->maplevel,sc->maxhp,sc->maxsp,
  		sc->maxgrace);
      else if(!strncmp(sc->killer,"left",MAX_NAME))
! 	sprintf(retbuf,"%3d %10ld %s left the game on map %s [%d][%d][%d].",
!             sc->position,sc->exp,sc->name,sc->maplevel,sc->maxhp,sc->maxsp,
  		sc->maxgrace);
      else
! 	sprintf(retbuf,"%3d %10ld %s was killed by %s on map %s [%d][%d][%d].",
!             sc->position,sc->exp,sc->name,sc->killer,sc->maplevel,
              sc->maxhp,sc->maxsp,sc->maxgrace);
      return retbuf;
  }
--- 143,158 ----
      static char retbuf[MAX_BUF];
  
      if(!strncmp(sc->killer,"quit",MAX_NAME))
! 	sprintf(retbuf,"%3d %10ld %s the %s quit the game on map %s [%d][%d][%d].",
!             sc->position,sc->exp,sc->name,sc->title,sc->maplevel,sc->maxhp,sc->maxsp,
  		sc->maxgrace);
      else if(!strncmp(sc->killer,"left",MAX_NAME))
! 	sprintf(retbuf,"%3d %10ld %s the %s left the game on map %s [%d][%d][%d].",
!             sc->position,sc->exp,sc->name,sc->title,sc->maplevel,sc->maxhp,sc->maxsp,
  		sc->maxgrace);
      else
! 	sprintf(retbuf,"%3d %10ld %s the %s was killed by %s on map %s [%d][%d][%d].",
!             sc->position,sc->exp,sc->name,sc->title,sc->killer,sc->maplevel,
              sc->maxhp,sc->maxsp,sc->maxgrace);
      return retbuf;
  }
*** crossfire-0.94.0//server/gods.c	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/server/gods.c	Sun Apr 12 21:44:29 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_apply_c =
!  *   "$Id: gods.c,v 1.10 1998/02/08 02:20:31 master Exp master $";
   */
  /*
      CrossFire, A Multiplayer game for X-windows
--- 1,6 ----
  /*
   * static char *rcsid_apply_c =
!  *   "$Id: gods.c,v 1.11 1998/04/12 21:42:25 master Exp master $";
   */
  /*
      CrossFire, A Multiplayer game for X-windows
***************
*** 221,227 ****
  
    for(tmp=op->inv;tmp&&number;tmp=tmp->below)
      if(tmp->type==type&&QUERY_FLAG(tmp,FLAG_APPLIED)) { 
! 	apply(op,tmp); /* this should unapply things properly */ 
  	number--;
      }
  }
--- 221,227 ----
  
    for(tmp=op->inv;tmp&&number;tmp=tmp->below)
      if(tmp->type==type&&QUERY_FLAG(tmp,FLAG_APPLIED)) { 
! 	apply(op,tmp,0); /* this should unapply things properly */ 
  	number--;
      }
  }
*** crossfire-0.94.0//server/init.c	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/server/init.c	Sun Apr 12 21:44:51 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_init_c =
!  *   "$Id: init.c,v 1.50 1998/02/08 02:22:14 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_init_c =
!  *   "$Id: init.c,v 1.50 1998/02/08 02:22:14 master Exp $";
   */
  
  /*
*** crossfire-0.94.0//server/input.c	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/server/input.c	Sun Apr 12 21:45:20 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_input_c =
!  *   "$Id: input.c,v 1.62 1998/02/08 02:22:47 master Exp master $";
   */
  /*
      CrossFire, A Multiplayer game for X-windows
--- 1,6 ----
  /*
   * static char *rcsid_input_c =
!  *   "$Id: input.c,v 1.63 1998/04/12 21:44:52 master Exp master $";
   */
  /*
      CrossFire, A Multiplayer game for X-windows
***************
*** 75,114 ****
  {
  
    return NULL;
- }
- 
- /*
-  * Check if an item op can be put into a sack. If pl exists then tell
-  * a player the reason of failure.
-  * returns 1 if it will fit, 0 if it will not.  nrof is the number of
-  * objects (op) we want to put in.  We specify it separately instead of
-  * using op->nrof because often times, a player may have specified a
-  * certain number of objects to drop, so we can pass that number, and
-  * not need to use split_ob and stuff.
-  */
- int sack_can_hold (object *pl, object *sack, object *op, int nrof) {
-     char buf[MAX_BUF];
-     buf[0] = 0;
- 
-     if (! QUERY_FLAG (sack, FLAG_APPLIED))
- 	sprintf (buf, "%s is not active.", query_name(sack));
-     if (sack == op)
- 	sprintf (buf, "You can't put %s into itself.", query_name(sack));
-     if (sack->race && (sack->race != op->race || op->type == CONTAINER
- 		       || (sack->stats.food && sack->stats.food != op->type)))
- 	sprintf (buf, "You can put only %s into %s.", sack->race,
- 		 query_name(sack));
-     if (op->type == SPECIAL_KEY && sack->slaying && op->slaying)
- 	sprintf (buf, "You don't want put the key into %s.", query_name(sack));
-     if (sack->weight_limit && sack->carrying + (nrof ? nrof : 1) * 
- 	op->weight * (100 - sack->stats.Str) / 100  > sack->weight_limit)
- 	sprintf (buf, "That won't fit in %s!", query_name(sack));
-     if (buf[0]) {
- 	if (pl)
- 	    new_draw_info(NDI_UNIQUE, 0,pl, buf);
- 	return 0;
-     }
-     return 1;
  }
  
  
--- 75,80 ----
*** crossfire-0.94.0//server/login.c	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/server/login.c	Sun Apr 12 21:45:53 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_login_c =
!  *   "$Id: login.c,v 1.50 1998/02/08 02:24:04 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_login_c =
!  *   "$Id: login.c,v 1.51 1998/04/12 21:45:20 master Exp master $";
   */
  
  /*
***************
*** 30,35 ****
--- 30,36 ----
  #include <sproto.h>
  #endif
  #include <spells.h>
+ #include <loader.h>
  
  extern spell spells[NROFREALSPELLS];
  extern void sub_weight (object *, signed long);
***************
*** 667,678 ****
          }
        }
  
        /* sigh */
        free_object (op);
        op = pl->ob = LoadObject (fp, NULL);
!       /* Somehow, the game worked before without this line - relied
!        * on getting the object back that we just freed? */
        op->contr = pl;
        CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER);
  
        x=op->x; y=op->y;
--- 668,683 ----
          }
        }
  
+ #if 0
        /* sigh */
        free_object (op);
        op = pl->ob = LoadObject (fp, NULL);
! #endif
!       reset_object(op);
        op->contr = pl;
+       pl->ob = op;
+       load_object(fp, op, LO_NEWFILE);
+ 
        CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER);
  
        x=op->x; y=op->y;
*** crossfire-0.94.0//server/main.c	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/server/main.c	Sun Apr 12 21:46:42 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_main_c =
!  *    "$Id: main.c,v 1.42 1998/02/08 02:26:51 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_main_c =
!  *    "$Id: main.c,v 1.43 1998/04/12 21:45:54 master Exp master $";
   */
  
  /*
***************
*** 34,39 ****
--- 34,43 ----
  extern char *crypt(const char *, const char *);
  #endif
  
+ #if defined(linux)
+ #include <crypt.h>
+ #endif
+ 
  #include <version.h>
  #include <global.h>
  #ifndef __CEXTRACT__
***************
*** 768,773 ****
--- 772,779 ----
  	  XFreeGC(pl->gdisp, pl->gc_inv_text);
  	if(pl->gc_inv_icon)
  	  XFreeGC(pl->gdisp, pl->gc_inv_icon);
+ 	if(pl->gc_inv_status_icon)
+ 	  XFreeGC(pl->gdisp, pl->gc_inv_status_icon);
  	if(pl->gc_look_text)
  	  XFreeGC(pl->gdisp, pl->gc_look_text);
  	if(pl->gc_look_icon)
*** crossfire-0.94.0//server/monster.c	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/server/monster.c	Sun Apr 12 21:49:11 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_monster_c =
!  *    "$Id: monster.c,v 1.36 1998/02/08 02:29:11 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_monster_c =
!  *    "$Id: monster.c,v 1.37 1998/04/12 21:46:43 master Exp master $";
   */
  
  /*
***************
*** 558,564 ****
      return 0;
    }
    if(wand->stats.food<=0) {
!     apply(head,wand);
      CLEAR_FLAG(head, FLAG_READY_WAND);
      if (wand->arch) {
        CLEAR_FLAG(wand, FLAG_ANIMATE);
--- 558,564 ----
      return 0;
    }
    if(wand->stats.food<=0) {
!     apply(head,wand,0);
      CLEAR_FLAG(head, FLAG_READY_WAND);
      if (wand->arch) {
        CLEAR_FLAG(wand, FLAG_ANIMATE);
***************
*** 657,663 ****
    }
    if((arrow=find_arrow(head,bow->race)) == NULL) {
      /* Out of arrows */
!     apply(head,bow);
      CLEAR_FLAG(head, FLAG_READY_BOW);
      return 0;
    }
--- 657,663 ----
    }
    if((arrow=find_arrow(head,bow->race)) == NULL) {
      /* Out of arrows */
!     apply(head,bow,0);
      CLEAR_FLAG(head, FLAG_READY_BOW);
      return 0;
    }
***************
*** 692,704 ****
        break;
    if(other_weap==NULL) /* No other weapons */
      return 1;
!   if (!apply(who,item)) {
      LOG(llevMonster,"Can't wield %s(%d).\n",item->name,item->count);
      return 0;
    }
    if(who->stats.dam < prev_dam && !QUERY_FLAG(other_weap,FLAG_FREED)) {
      /* New weapon was worse.  (Note ^: Could have been freed by merging) */
!     if (!apply(who,other_weap))
        LOG(llevMonster,"Can't rewield %s(%d).\n",item->name,item->count);
      return 0;
    }
--- 692,704 ----
        break;
    if(other_weap==NULL) /* No other weapons */
      return 1;
!   if (!apply(who,item,0)) {
      LOG(llevMonster,"Can't wield %s(%d).\n",item->name,item->count);
      return 0;
    }
    if(who->stats.dam < prev_dam && !QUERY_FLAG(other_weap,FLAG_FREED)) {
      /* New weapon was worse.  (Note ^: Could have been freed by merging) */
!     if (!apply(who,other_weap,0))
        LOG(llevMonster,"Can't rewield %s(%d).\n",item->name,item->count);
      return 0;
    }
***************
*** 714,726 ****
        break;
    if (other_armour == NULL) /* No other armour, use the new */
      return 1;
!   if (!apply(who, item)) {
      LOG(llevMonster, "Can't take off %s(%d).\n",item->name,item->count);
      return 0;
    }
    if(who->stats.ac < prev_ac && !QUERY_FLAG(other_armour,FLAG_FREED)) {
      /* New armour was worse. *Note ^: Could have been freed by merging) */
!     if (!apply(who, other_armour))
        LOG(llevMonster,"Can't rewear %s(%d).\n", item->name, item->count);
      return 0;
    }
--- 714,726 ----
        break;
    if (other_armour == NULL) /* No other armour, use the new */
      return 1;
!   if (!apply(who, item,0)) {
      LOG(llevMonster, "Can't take off %s(%d).\n",item->name,item->count);
      return 0;
    }
    if(who->stats.ac < prev_ac && !QUERY_FLAG(other_armour,FLAG_FREED)) {
      /* New armour was worse. *Note ^: Could have been freed by merging) */
!     if (!apply(who, other_armour,0))
        LOG(llevMonster,"Can't rewear %s(%d).\n", item->name, item->count);
      return 0;
    }
***************
*** 829,843 ****
      switch (tmp->type) {
      case HANDLE:
        if (monster->will_apply&1)
!         apply(monster,tmp);
        break;
      case TREASURE:
        if (monster->will_apply&2)
!         apply(monster,tmp);
        break;
      case SCROLL:  /* Ideally, they should wait until they meet a player */
        if (QUERY_FLAG(monster,FLAG_USE_SCROLL))
!         apply(monster,tmp); 
        break;
      }
    }
--- 829,843 ----
      switch (tmp->type) {
      case HANDLE:
        if (monster->will_apply&1)
!         apply(monster,tmp,0);
        break;
      case TREASURE:
        if (monster->will_apply&2)
!         apply(monster,tmp,0);
        break;
      case SCROLL:  /* Ideally, they should wait until they meet a player */
        if (QUERY_FLAG(monster,FLAG_USE_SCROLL))
!         apply(monster,tmp,0); 
        break;
      }
    }
***************
*** 868,874 ****
          SET_FLAG(mon, FLAG_READY_BOW);
          LOG(llevMonster,"Found correct bow for arrows.\n");
          if(!QUERY_FLAG(bow, FLAG_APPLIED))
!           apply(mon,bow);
          break;
        }
    }
--- 868,874 ----
          SET_FLAG(mon, FLAG_READY_BOW);
          LOG(llevMonster,"Found correct bow for arrows.\n");
          if(!QUERY_FLAG(bow, FLAG_APPLIED))
!           apply(mon,bow,0);
          break;
        }
    }
***************
*** 906,912 ****
      case SKILL:
  #ifdef ALLOW_SKILLS
        if((flag=QUERY_FLAG(mon,FLAG_CAN_USE_SKILL))) {
!         if(!QUERY_FLAG(item,FLAG_APPLIED)) apply(mon,item);
          if (item->type==SKILL&&present_in_ob(SKILL,mon)!=NULL)
  	  SET_FLAG(mon, FLAG_READY_SKILL);
        }
--- 906,912 ----
      case SKILL:
  #ifdef ALLOW_SKILLS
        if((flag=QUERY_FLAG(mon,FLAG_CAN_USE_SKILL))) {
!         if(!QUERY_FLAG(item,FLAG_APPLIED)) apply(mon,item,0);
          if (item->type==SKILL&&present_in_ob(SKILL,mon)!=NULL)
  	  SET_FLAG(mon, FLAG_READY_SKILL);
        }
***************
*** 924,930 ****
      if (((!(mon->can_apply&32))&&flag) ||((mon->can_apply&32)&&(!flag))) {
          /* &32 reverses behaviour. See global.h */
          if(!QUERY_FLAG(item,FLAG_APPLIED))
!           apply(mon,item);
          if (item->type==BOW&&present_in_ob(item->stats.maxsp,mon)!=NULL)
  	  SET_FLAG(mon, FLAG_READY_BOW);
      }
--- 924,930 ----
      if (((!(mon->can_apply&32))&&flag) ||((mon->can_apply&32)&&(!flag))) {
          /* &32 reverses behaviour. See global.h */
          if(!QUERY_FLAG(item,FLAG_APPLIED))
!           apply(mon,item,0);
          if (item->type==BOW&&present_in_ob(item->stats.maxsp,mon)!=NULL)
  	  SET_FLAG(mon, FLAG_READY_BOW);
      }
***************
*** 1129,1134 ****
--- 1129,1149 ----
      check_earthwalls(op,newx,newy);
    if(op->will_apply&8)
      check_doors(op,newx,newy);
+ 
+   /* 0.94.1 - I got a stack trace that showed it crash with remove_ob trying
+    * to remove a removed object, and this function was the culprit.  A possible
+    * guess I have is that check_doors above ran into a trap, killing the
+    * monster.
+    *
+    * Unfortunately, it doesn't appear that the calling functions of move_object
+    * deal very well with op being killed, so all this might do is just
+    * migrate the problem someplace else.
+    */
+   if (QUERY_FLAG(op, FLAG_REMOVED)) {
+     LOG(llevDebug,"move_object: monster has been removed - will not process further\n");
+     /* Was not successful, but don't want to try and move again */
+     return 1;
+   }
    if(op->head)
      return 1;
    remove_ob(op);
*** crossfire-0.94.0//server/move.c	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/server/move.c	Sun Apr 12 21:49:58 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_move_c =
!  *    "$Id: move.c,v 1.14 1997/03/09 05:12:37 master Exp $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_move_c =
!  *    "$Id: move.c,v 1.15 1998/04/12 21:49:11 master Exp master $";
   */
  
  /*
***************
*** 187,197 ****
          continue;
        other_teleporter=get_map_ob(teleporter->map,
                                    teleporter->x+i,teleporter->y+j);
!       if(other_teleporter==NULL
! 	 || (other_teleporter->type!=tele_type
! 	     && (other_teleporter->above==NULL
! 		 || other_teleporter->above->type!=tele_type)))
!         continue;
        altern[nrofalt++]=other_teleporter;
      }
    if(!nrofalt) {
--- 187,197 ----
          continue;
        other_teleporter=get_map_ob(teleporter->map,
                                    teleporter->x+i,teleporter->y+j);
!       while (other_teleporter) {
! 	if (other_teleporter->type == tele_type) break;
! 	other_teleporter = other_teleporter->above;
!       }
!       if (!other_teleporter) continue;
        altern[nrofalt++]=other_teleporter;
      }
    if(!nrofalt) {
*** crossfire-0.94.0//server/newitem.c	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/server/newitem.c	Sun Mar  1 09:37:40 1998
***************
*** 306,310 ****
--- 306,311 ----
  void esrv_send_item(object *pl, object*op) {}
  void esrv_send_inventory(object *pl, object *op) {}
  void esrv_draw_look(object *pl) {}
+ void esrv_update_item(int flags, object *pl, object *op) {}
  #endif
  
*** crossfire-0.94.0//server/newsocket.c	Sun Feb  8 05:26:18 1998
--- crossfire-0.94.1/server/newsocket.c	Sun Apr 12 21:51:34 1998
***************
*** 1,7 ****
  
  /*
   * static char *rcsid_sockets_c =
!  *    "$Id: newsocket.c,v 1.4 1998/02/08 03:08:38 master Exp master $";
   */
  
  /*
--- 1,7 ----
  
  /*
   * static char *rcsid_sockets_c =
!  *    "$Id: newsocket.c,v 1.5 1998/04/12 21:50:12 master Exp master $";
   */
  
  /*
***************
*** 111,117 ****
  	    /* In non blocking mode, EAGAIN is set when there is no
  	     * data available.
  	     */
! 	    if (errno!=EAGAIN) {
  		perror("ReadPacket got an error.");
  		LOG(llevDebug,"ReadPacket got error %d, returning 0",errno);
  	    }
--- 111,117 ----
  	    /* In non blocking mode, EAGAIN is set when there is no
  	     * data available.
  	     */
! 	    if (errno!=EAGAIN && errno!=EWOULDBLOCK) {
  		perror("ReadPacket got an error.");
  		LOG(llevDebug,"ReadPacket got error %d, returning 0",errno);
  	    }
***************
*** 133,139 ****
      do {
  	stat = read(fd, sl->buf+ sl->len, toread);
  	if (stat<0) {
! 	    if (errno!=EAGAIN) {
  		perror("ReadPacket got an error.");
  		LOG(llevDebug,"ReadPacket got error %d, returning 0",errno);
  	    }
--- 133,139 ----
      do {
  	stat = read(fd, sl->buf+ sl->len, toread);
  	if (stat<0) {
! 	    if (errno!=EAGAIN && errno!=EWOULDBLOCK) {
  		perror("ReadPacket got an error.");
  		LOG(llevDebug,"ReadPacket got error %d, returning 0",errno);
  	    }
*** crossfire-0.94.0//server/player.c	Sun Feb  8 05:26:19 1998
--- crossfire-0.94.1/server/player.c	Sun Apr 12 21:56:08 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_player_c =
!  *   "$Id: player.c,v 1.68 1998/02/08 03:09:05 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_player_c =
!  *   "$Id: player.c,v 1.69 1998/04/12 21:51:35 master Exp master $";
   */
  
  /*
***************
*** 1323,1328 ****
--- 1323,1353 ----
    }
  }
  
+ /*
+  * Finds a matching key for a special door.  This function will descend
+  * into keyrings, but not other containers.
+  */
+ 
+ static object *FindKey(object *Door, object *ob)
+ {
+     while (ob!=NULL) {
+ 	/* Only search/descend into keyrings.  Thus, players can 'hide'
+ 	 * keys that they don't want auto used in other containers.
+ 	 */
+ 	if (ob->type==CONTAINER && !strcmp(ob->race,"keys")) {
+ 	    object *t;
+ 
+ 	    t=FindKey(Door,ob->inv);
+ 	    if (t!=NULL) return t;
+ 	}
+ 	else if (ob->type==SPECIAL_KEY && ob->slaying==Door->slaying) {
+ 	    return ob;
+ 	}
+ 	ob=ob->below;
+     }
+     return NULL;
+ }
+ 
  /* This function is just part of a breakup from move_player.
   * It should keep the code cleaner.
   * When this is called, the players direction has been updated
***************
*** 1395,1405 ****
       */
  
      if(tmp->type==LOCKED_DOOR) {
        tmp2=op->inv;
        while(tmp2 && (tmp2->type != SPECIAL_KEY ||
  	    tmp2->slaying != tmp->slaying)) /* Find the key */
  	tmp2=tmp2->below;
! 
        if(tmp2) {
  	  decrease_ob_nr(tmp2, 1); /* Use the key */
  	  remove_door2(tmp); /* remove door without violence ;-) */
--- 1420,1433 ----
       */
  
      if(tmp->type==LOCKED_DOOR) {
+ #if 0
        tmp2=op->inv;
        while(tmp2 && (tmp2->type != SPECIAL_KEY ||
  	    tmp2->slaying != tmp->slaying)) /* Find the key */
  	tmp2=tmp2->below;
! #else
!       tmp2=FindKey(tmp,op->inv);
! #endif
        if(tmp2) {
  	  decrease_ob_nr(tmp2, 1); /* Use the key */
  	  remove_door2(tmp); /* remove door without violence ;-) */
***************
*** 1702,1708 ****
              op->contr->mark_count=tmp->count;
              new_draw_info_format(NDI_UNIQUE,0,op,"Marked item %s", query_name(tmp));
  	} else {
! 	    apply(op,tmp);
  	    if (op->contr->show_what == show_applied || op->contr->show_what==show_unapplied)
  		draw_inventory(op);
  	}
--- 1730,1736 ----
              op->contr->mark_count=tmp->count;
              new_draw_info_format(NDI_UNIQUE,0,op,"Marked item %s", query_name(tmp));
  	} else {
! 	    apply(op,tmp,0);
  	    if (op->contr->show_what == show_applied || op->contr->show_what==show_unapplied)
  		draw_inventory(op);
  	}
***************
*** 1790,1796 ****
        examine(op,tmp);
        return 1;
       case 2:
!       apply(op,tmp);
        draw_look(op);
        return 1;
       case 3:
--- 1818,1824 ----
        examine(op,tmp);
        return 1;
       case 2:
!       apply(op,tmp,0);
        draw_look(op);
        return 1;
       case 3:
***************
*** 1811,1817 ****
        for(tmp=inv,i=0;tmp!=NULL&&i<(y-13)/13;tmp=tmp->below,i++);
        if(tmp!=NULL) {
        if(button==1)
! 	apply(op,tmp);
        else
  	drop(op,tmp);
        inventory(op,NULL);
--- 1839,1845 ----
        for(tmp=inv,i=0;tmp!=NULL&&i<(y-13)/13;tmp=tmp->below,i++);
        if(tmp!=NULL) {
        if(button==1)
! 	apply(op,tmp,0);
        else
  	drop(op,tmp);
        inventory(op,NULL);
***************
*** 2253,2259 ****
  	  pl->name, tag);
        return;
      }
!     apply (pl, op);
  }
  
  void esrv_move_object (object *pl, long to, long tag, long nrof)
--- 2281,2287 ----
  	  pl->name, tag);
        return;
      }
!     apply (pl, op,0);
  }
  
  void esrv_move_object (object *pl, long to, long tag, long nrof)
***************
*** 2426,2432 ****
  			  (tmp->type==FOOD||tmp->type==DRINK||tmp->type==POISON))
  			  {
  		new_draw_info(NDI_UNIQUE, 0,op,"You blindly grab for a bite of food.");
! 	apply(op,tmp);
  	if(op->stats.food>=0||op->stats.hp<0)
  	  break;
        }
--- 2454,2460 ----
  			  (tmp->type==FOOD||tmp->type==DRINK||tmp->type==POISON))
  			  {
  		new_draw_info(NDI_UNIQUE, 0,op,"You blindly grab for a bite of food.");
! 	apply(op,tmp,0);
  	if(op->stats.food>=0||op->stats.hp<0)
  	  break;
        }
*** crossfire-0.94.0//server/rune.c	Sun Feb  8 05:26:19 1998
--- crossfire-0.94.1/server/rune.c	Sun Apr 12 21:56:09 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_rune_c =
!  *   "$Id: rune.c,v 1.18 1998/02/08 03:13:03 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_rune_c =
!  *   "$Id: rune.c,v 1.18 1998/02/08 03:13:03 master Exp $";
   */
  
  /*
*** crossfire-0.94.0//server/shop.c	Sun Feb  8 05:26:19 1998
--- crossfire-0.94.1/server/shop.c	Sun Apr 12 21:56:29 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_shop_c =
!  *   "$Id: shop.c,v 1.35 1998/02/08 03:13:20 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_shop_c =
!  *   "$Id: shop.c,v 1.36 1998/04/12 21:56:09 master Exp master $";
   */
  
  /*
***************
*** 161,171 ****
        float diff;
  
        charisma = who->stats.Cha;  /* used for SK_BARGAINING modification */ 
!       if(who->contr->shoottype == range_skill && who->chosen_skill)
!          if(who->chosen_skill->stats.sp == SK_BARGAINING) { 
! 	    charisma = who->stats.Cha + (who->level+2)/3;
! 	    if(charisma>30) charisma = 30;
!          }
        if (cha_bonus[charisma]<=1.0) {
  	LOG(llevError,"Illegal charisma bonus, %d <=1.0", cha_bonus[charisma]);
  	diff=0.9;	/*pretty bad case */
--- 161,171 ----
        float diff;
  
        charisma = who->stats.Cha;  /* used for SK_BARGAINING modification */ 
! 
!       if (find_skill(who,SK_BARGAINING)) {
! 	charisma = who->stats.Cha + (who->level+2)/3;
! 	if(charisma>30) charisma = 30;
!       }
        if (cha_bonus[charisma]<=1.0) {
  	LOG(llevError,"Illegal charisma bonus, %d <=1.0", cha_bonus[charisma]);
  	diff=0.9;	/*pretty bad case */
*** crossfire-0.94.0//server/skills.c	Sun Feb  8 05:26:19 1998
--- crossfire-0.94.1/server/skills.c	Mon Mar  9 10:14:36 1998
***************
*** 391,493 ****
    return success;
  }
  
! /* jump() - this is both a new type of movement for player/monsters and
!  * an attack as well. -b.t.
!  */ 
  
! int jump(object *pl, int dir) 
! {
!  int spaces=0,stats;
!  int str = get_skill_stat1(pl); 
!  int dex = get_skill_stat2(pl);
! 
!  dex = dex ? dex : 15;
!  str = str ? str : 10; 
! 
!         stats=str*str*str*dex;
! 
!  	if(pl->carrying!=0)		/* don't want div by zero !! */	 
! 	     spaces=(int) (stats/pl->carrying);
!  	else
! 		spaces=2;	/* pl has no objects - gets the far jump */ 
! 
!  	if(spaces>2)
! 		 spaces = 2;
!  	else if(spaces==0) {
!   		new_draw_info(NDI_UNIQUE, 0,pl,"You are carrying too much weight to jump.");
! 		return 0;
!  	}
!  	return attempt_jump(pl,dir,spaces);
  }
  
- int attempt_jump (object *pl, int dir, int spaces) {
-   object *tmp;
-   int i,exp=0,dx=freearr_x[dir],dy=freearr_y[dir];
  
!  /* Jump loop. Go through spaces opject wants to jump. Halt the
!   * jump if a wall or creature is in the way. We set FLAG_FLYING
!   * temporarily to allow player to aviod exits/archs that are not 
!   * fly_on, fly_off. This will also prevent pickup of objects 
!   * while jumping over them.  
!   */ 
! 
!   remove_ob(pl);
!   SET_FLAG(pl,FLAG_FLYING);
!   for(i=0;i<=spaces;i++) { 
!       if (out_of_map(pl->map,pl->x+dx,pl->y+dy)) {
! 	(void) stop_jump(pl,i,spaces);
! 	return calc_skill_exp(pl,NULL);
!       }
!       for(tmp=get_map_ob(pl->map,pl->x+dx,pl->y+dy);
!         tmp;tmp=tmp->above) { 
! 	   if(wall(tmp->map,tmp->x,tmp->y)) {           /* Jump into wall*/ 
!              new_draw_info(NDI_UNIQUE, 0,pl,"Your jump is blocked.");
! 	     (void) stop_jump(pl,i,spaces);
! 	     return 0;
! 	   } 
! 	   if(QUERY_FLAG(tmp,FLAG_MONSTER)          /* Jump into creature */ 
! 	            || tmp->type==PLAYER ) {   
!              new_draw_info_format(NDI_UNIQUE, 0,pl,"You jump into%s%s.", 
! 	       tmp->type == PLAYER ? " " : " the ", tmp->name);
  #ifdef SIMPLE_PARTY_SYSTEM
! 	     if(tmp->type!=PLAYER || 
! 		(pl->type==PLAYER && pl->contr->party_number==-1) ||
! 		(pl->type==PLAYER && tmp->type==PLAYER &&
! 		 pl->contr->party_number!=tmp->contr->party_number)) 
  #endif
   	     	    exp = skill_attack(tmp,pl,pl->facing,"kicked"); /* pl makes an attack */ 
! 	     (void) stop_jump(pl,i,spaces);
! 	     return exp;  /* note that calc_skill_exp() is already called by skill_attack() */ 
! 	   }
! 	   if(tmp->type==EXIT			     /* pl jump through exit */ 
! 		&& QUERY_FLAG(tmp, FLAG_FLY_ON)) { 
!              pl->x+=dx,pl->y+=dy;
! 	     (void) stop_jump(pl,i,spaces);
! 	     return calc_skill_exp(pl,NULL);
! 	   }
!       }
!       pl->x+=dx;
!       pl->y+=dy;
!   }
!   (void) stop_jump(pl,i,spaces);
!   return calc_skill_exp(pl,NULL);
  }
  
! /* stop_jump() - End of jump. Clear flags, restore the map, and 
!  * freeze the jumper a while to simulate the exhaustion
!  * of jumping.
!  */
! 
! int stop_jump(object *pl, int dist, int spaces) {
!  /* int load=dist/(pl->speed*spaces); */ 
  
!   CLEAR_FLAG(pl,FLAG_FLYING);
!   insert_ob_in_map(pl,pl->map);
!   if (pl->type==PLAYER) draw(pl);  
!  /* pl->speed_left= (int) -FABS((load*8)+1); */ 
!   return 0;
  }
  
  /* skill_ident() - this code is supposed to allow players to identify 
   * classes of objects with the various "auto-ident" skills. Player must 
   * have unidentified objects of the right type in order for the skill
--- 391,498 ----
    return success;
  }
  
! /* stop_jump() - End of jump. Clear flags, restore the map, and 
!  * freeze the jumper a while to simulate the exhaustion
!  * of jumping.
!  */
  
! static int stop_jump(object *pl, int dist, int spaces) {
!     /* int load=dist/(pl->speed*spaces); */ 
! 
!     CLEAR_FLAG(pl,FLAG_FLYING);
!     insert_ob_in_map(pl,pl->map);
!     if (pl->type==PLAYER) draw(pl);  
! 
!     /* pl->speed_left= (int) -FABS((load*8)+1); */ 
!     return 0;
  }
  
  
! static int attempt_jump (object *pl, int dir, int spaces) {
!     object *tmp;
!     int i,exp=0,dx=freearr_x[dir],dy=freearr_y[dir];
! 
!     /* Jump loop. Go through spaces opject wants to jump. Halt the
!      * jump if a wall or creature is in the way. We set FLAG_FLYING
!      * temporarily to allow player to aviod exits/archs that are not 
!      * fly_on, fly_off. This will also prevent pickup of objects 
!      * while jumping over them.  
!      */ 
! 
!     remove_ob(pl);
!     SET_FLAG(pl,FLAG_FLYING);
!     for(i=0;i<=spaces;i++) { 
! 	if (out_of_map(pl->map,pl->x+dx,pl->y+dy)) {
! 	    (void) stop_jump(pl,i,spaces);
! 	    return calc_skill_exp(pl,NULL);
! 	}
! 	for(tmp=get_map_ob(pl->map,pl->x+dx,pl->y+dy); tmp;tmp=tmp->above) { 
! 	    if(wall(tmp->map,tmp->x,tmp->y)) {           /* Jump into wall*/ 
! 		new_draw_info(NDI_UNIQUE, 0,pl,"Your jump is blocked.");
! 		(void) stop_jump(pl,i,spaces);
! 		return 0;
! 	    }
! 	    /* Jump into creature */ 
! 	    if(QUERY_FLAG(tmp,FLAG_MONSTER) || tmp->type==PLAYER ) {   
! 		new_draw_info_format(NDI_UNIQUE, 0,pl,"You jump into%s%s.", 
! 		    tmp->type == PLAYER ? " " : " the ", tmp->name);
  #ifdef SIMPLE_PARTY_SYSTEM
! 		if(tmp->type!=PLAYER || 
! 		   (pl->type==PLAYER && pl->contr->party_number==-1) ||
! 		   (pl->type==PLAYER && tmp->type==PLAYER &&
! 		    pl->contr->party_number!=tmp->contr->party_number)) 
  #endif
   	     	    exp = skill_attack(tmp,pl,pl->facing,"kicked"); /* pl makes an attack */ 
! 		(void) stop_jump(pl,i,spaces);
! 		return exp;  /* note that calc_skill_exp() is already called by skill_attack() */ 
! 	    }
! 	     /* If the space has fly on set (no matter what the space is),
! 	      * we should get the effects - after all, the player is
! 	      * effectively flying.
! 	      */
! 	    if(QUERY_FLAG(tmp, FLAG_FLY_ON)) { 
! 		pl->x+=dx,pl->y+=dy;
! 		(void) stop_jump(pl,i,spaces);
! 		return calc_skill_exp(pl,NULL);
! 	    }
! 	}
! 	pl->x+=dx;
! 	pl->y+=dy;
!     }
!     (void) stop_jump(pl,i,spaces);
!     return calc_skill_exp(pl,NULL);
  }
  
! /* jump() - this is both a new type of movement for player/monsters and
!  * an attack as well. -b.t.
!  */ 
  
! int jump(object *pl, int dir) 
! {
!     int spaces=0,stats;
!     int str = get_skill_stat1(pl); 
!     int dex = get_skill_stat2(pl);
! 
!     dex = dex ? dex : 15;
!     str = str ? str : 10; 
! 
!     stats=str*str*str*dex;
! 
!     if(pl->carrying!=0)		/* don't want div by zero !! */	 
! 	spaces=(int) (stats/pl->carrying);
!     else
! 	spaces=2;	/* pl has no objects - gets the far jump */ 
! 
!     if(spaces>2)
! 	 spaces = 2;
!     else if(spaces==0) {
! 	new_draw_info(NDI_UNIQUE, 0,pl,"You are carrying too much weight to jump.");
! 	return 0;
!     }
!     return attempt_jump(pl,dir,spaces);
  }
  
+ 
  /* skill_ident() - this code is supposed to allow players to identify 
   * classes of objects with the various "auto-ident" skills. Player must 
   * have unidentified objects of the right type in order for the skill
***************
*** 1086,1092 ****
      if(scroll->stats.sp &&  (RANDOM()%(scroll->level*2+1))>SK_level(pl)) {
           	new_draw_info_format(NDI_UNIQUE,0,pl,
  			"Oops! You accidently read it while trying to write on it.");
! 		apply(pl,scroll);
  		change_skill(pl,SK_INSCRIPTION);
  		return 0;
      }
--- 1091,1097 ----
      if(scroll->stats.sp &&  (RANDOM()%(scroll->level*2+1))>SK_level(pl)) {
           	new_draw_info_format(NDI_UNIQUE,0,pl,
  			"Oops! You accidently read it while trying to write on it.");
! 		apply(pl,scroll,0);
  		change_skill(pl,SK_INSCRIPTION);
  		return 0;
      }
*** crossfire-0.94.0//server/skill_util.c	Sun Feb  8 05:26:19 1998
--- crossfire-0.94.1/server/skill_util.c	Fri Mar 13 10:35:46 1998
***************
*** 1018,1024 ****
  #endif
  
  /* print out skills by category */
!   for (i=0;i<=nrofexpcat;i++) { 
      is_first=1;
      if(i==nrofexpcat) i=EXP_NONE; /* skip to misc exp category */
  #ifdef LINKED_SKILL_LIST
--- 1018,1026 ----
  #endif
  
  /* print out skills by category */
!   for (i=0;i<=nrofexpcat;i++) {
!     char Special[100];
!     Special[0]='\0';
      is_first=1;
      if(i==nrofexpcat) i=EXP_NONE; /* skip to misc exp category */
  #ifdef LINKED_SKILL_LIST
***************
*** 1039,1048 ****
  	      int k=(length-15-strlen(tmp_exp->name)); 
  	      char tmpbuf[40];
  	      strcpy(tmpbuf,tmp_exp->name);
! 	      while(k>0) {k--; strcat(tmpbuf,".");} 
                new_draw_info_format(NDI_UNIQUE,0,op,"%slvl:%3d (xp:%d/%d)",
  		tmpbuf,tmp_exp->level,tmp_exp->stats.exp,
  		level_exp(tmp_exp->level+1, op->expmul));
              } else if(i==EXP_NONE) { 
                new_draw_info(NDI_UNIQUE,0,op,"misc.");
  	    } 
--- 1041,1054 ----
  	      int k=(length-15-strlen(tmp_exp->name)); 
  	      char tmpbuf[40];
  	      strcpy(tmpbuf,tmp_exp->name);
! 	      while(k>0) {k--; strcat(tmpbuf,".");}
                new_draw_info_format(NDI_UNIQUE,0,op,"%slvl:%3d (xp:%d/%d)",
  		tmpbuf,tmp_exp->level,tmp_exp->stats.exp,
  		level_exp(tmp_exp->level+1, op->expmul));
+ 	      if (strcmp(tmp_exp->name,"physique")==0)
+ 		{
+ 		  sprintf(Special,"You can handle %d weapon improvements.",tmp_exp->level/5+5);
+ 		}
              } else if(i==EXP_NONE) { 
                new_draw_info(NDI_UNIQUE,0,op,"misc.");
  	    } 
***************
*** 1059,1066 ****
  		skills[tmp->stats.sp].name);
  
            new_draw_info(NDI_UNIQUE,0,op,buf);
!       } 
      }
    }
  }    
  
--- 1065,1076 ----
  		skills[tmp->stats.sp].name);
  
            new_draw_info(NDI_UNIQUE,0,op,buf);
!       }
      }
+     if (Special[0]!='\0')
+       {
+ 	new_draw_info(NDI_UNIQUE,0,op,Special);
+       }
    }
  }    
  
*** crossfire-0.94.0//server/socket.c	Sun Feb  8 05:26:19 1998
--- crossfire-0.94.1/server/socket.c	Sun Apr 12 21:58:25 1998
***************
*** 1,7 ****
  
  /*
   * static char *rcsid_sockets_c =
!  *    "$Id: socket.c,v 1.32 1998/02/08 03:14:47 master Exp master $";
   */
  
  /*
--- 1,7 ----
  
  /*
   * static char *rcsid_sockets_c =
!  *    "$Id: socket.c,v 1.33 1998/04/12 21:58:15 master Exp master $";
   */
  
  /*
*** crossfire-0.94.0//server/sounds.c	Sun Feb  8 05:26:19 1998
--- crossfire-0.94.1/server/sounds.c	Sun Apr 12 21:58:25 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_sound_c =
!  *   "$Id: sounds.c,v 1.13 1998/02/08 03:15:24 master Exp master $";
   */
  
  /* Send bug reports to Raphael Quinet (quinet@montefiore.ulg.ac.be) */
--- 1,6 ----
  /*
   * static char *rcsid_sound_c =
!  *   "$Id: sounds.c,v 1.13 1998/02/08 03:15:24 master Exp $";
   */
  
  /* Send bug reports to Raphael Quinet (quinet@montefiore.ulg.ac.be) */
*** crossfire-0.94.0//server/spell_effect.c	Sun Feb  8 05:26:19 1998
--- crossfire-0.94.1/server/spell_effect.c	Sun Apr 12 21:59:09 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_newspells_c =
!  *   "$Id: spell_effect.c,v 1.22 1998/02/08 03:15:51 master Exp master $";
   */
  
  
--- 1,6 ----
  /*
   * static char *rcsid_newspells_c =
!  *   "$Id: spell_effect.c,v 1.23 1998/04/12 21:58:26 master Exp master $";
   */
  
  
***************
*** 225,231 ****
    for(tmp = op->inv; tmp != NULL; tmp = next) {
      next = tmp->below;
      if(QUERY_FLAG(tmp, FLAG_APPLIED))
!       apply(op,tmp);
      if(tmp->type == ABILITY) {
        remove_ob(tmp);
        free_object(tmp);
--- 225,231 ----
    for(tmp = op->inv; tmp != NULL; tmp = next) {
      next = tmp->below;
      if(QUERY_FLAG(tmp, FLAG_APPLIED))
!       apply(op,tmp,0);
      if(tmp->type == ABILITY) {
        remove_ob(tmp);
        free_object(tmp);
***************
*** 746,751 ****
--- 746,756 ----
    tmp->x=op->x+freearr_x[dir],tmp->y=op->y+freearr_y[dir];
    insert_ob_in_map(tmp,op->map);
  
+   if (QUERY_FLAG(tmp, FLAG_REMOVED)) {
+     new_draw_info(NDI_UNIQUE, 0,op,"Something destroys your wall");
+     return 0;
+   }
+ 
    /*  This code causes the wall to extend to a distance of 5 in
  		each direction, or until an obstruction is encountered. 
  		posblocked and negblocked help determine how far the
***************
*** 1889,1895 ****
            break; } 
          case SP_SHOW_INVIS:
  	    /* Might there be other objects that we can make visibile? */
! 	    if (tmp->invisible && (QUERY_FLAG(tmp, FLAG_MONSTER) || tmp->type==PLAYER)) {
  		if(RANDOM()%(SK_level(op)) > tmp->level/4) {
  		    tmp->invisible=0;
  		    done_one = 1;
--- 1894,1901 ----
            break; } 
          case SP_SHOW_INVIS:
  	    /* Might there be other objects that we can make visibile? */
! 	    if (tmp->invisible && (QUERY_FLAG(tmp, FLAG_MONSTER) || 
! 		tmp->type==PLAYER || tmp->type==HANDLE)) {
  		if(RANDOM()%(SK_level(op)) > tmp->level/4) {
  		    tmp->invisible=0;
  		    done_one = 1;
*** crossfire-0.94.0//server/spell_util.c	Sun Feb  8 05:26:19 1998
--- crossfire-0.94.1/server/spell_util.c	Sun Apr 12 22:00:39 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_spells_c =
!  *   "$Id: spell_util.c,v 1.23 1998/02/08 03:19:36 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_spells_c =
!  *   "$Id: spell_util.c,v 1.24 1998/04/12 21:59:10 master Exp master $";
   */
  
  /*
***************
*** 825,831 ****
    object *tmp,*head;
    for(tmp=get_map_ob(m,x,y);tmp!=NULL;tmp=tmp->above) {
      head=tmp->head==NULL?tmp:tmp->head;
!     if((QUERY_FLAG(op, FLAG_ALIVE) && head->immune & immune_stop) ||
         (head->stats.maxhp == op->stats.maxhp && head->type == op->type))
        return 0;
    }
--- 825,831 ----
    object *tmp,*head;
    for(tmp=get_map_ob(m,x,y);tmp!=NULL;tmp=tmp->above) {
      head=tmp->head==NULL?tmp:tmp->head;
!     if((QUERY_FLAG(head, FLAG_ALIVE) && head->immune & immune_stop) ||
         (head->stats.maxhp == op->stats.maxhp && head->type == op->type))
        return 0;
    }
***************
*** 958,966 ****
      tmp->level=SK_level(op); /* need to use the cleric level, not overall value -b.t. */ 
      tmp->x=x,tmp->y=y;
  #ifdef MULTIPLE_GODS /* holy word stuff */                
!     if((tmp->attacktype&AT_HOLYWORD)||(tmp->attacktype&AT_GODPOWER))
              if(!tailor_god_spell(tmp,op)) return 0;  
!     else /* god/holy word isnt really 'magic' */
  #endif
      if(magic)
        tmp->attacktype|=AT_MAGIC;  /* JWI cone attacks should be considered
--- 958,966 ----
      tmp->level=SK_level(op); /* need to use the cleric level, not overall value -b.t. */ 
      tmp->x=x,tmp->y=y;
  #ifdef MULTIPLE_GODS /* holy word stuff */                
!     if((tmp->attacktype&AT_HOLYWORD)||(tmp->attacktype&AT_GODPOWER)) {
              if(!tailor_god_spell(tmp,op)) return 0;  
!     } else /* god/holy word isnt really 'magic' */
  #endif
      if(magic)
        tmp->attacktype|=AT_MAGIC;  /* JWI cone attacks should be considered
*** crossfire-0.94.0//server/swap.c	Sun Feb  8 05:26:19 1998
--- crossfire-0.94.1/server/swap.c	Sun Apr 12 22:00:40 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_swap_c =
!  *    "$Id: swap.c,v 1.14 1998/02/08 03:20:10 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_swap_c =
!  *    "$Id: swap.c,v 1.14 1998/02/08 03:20:10 master Exp $";
   */
  
  /*
*** crossfire-0.94.0//server/time.c	Sun Feb  8 05:26:19 1998
--- crossfire-0.94.1/server/time.c	Sun Apr 12 22:01:00 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_time_c =
!  *    "$Id: time.c,v 1.36 1998/02/08 03:20:30 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_time_c =
!  *    "$Id: time.c,v 1.37 1998/04/12 22:00:40 master Exp master $";
   */
  
  /*
***************
*** 370,376 ****
        op->speed = 0;
        update_ob_speed(op);
        SET_FLAG(op, FLAG_WALK_ON);
!       while(op->above!=NULL && apply(op->above,op))
          ;
      }
      SET_ANIMATION(op, op->stats.wc);
--- 370,376 ----
        op->speed = 0;
        update_ob_speed(op);
        SET_FLAG(op, FLAG_WALK_ON);
!       while(op->above!=NULL && apply(op->above,op,0))
          ;
      }
      SET_ANIMATION(op, op->stats.wc);
*** crossfire-0.94.0//server/xio.c	Sun Feb  8 05:26:19 1998
--- crossfire-0.94.1/server/xio.c	Sun Apr 12 22:01:35 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_xio_c =
!  *   "$Id: xio.c,v 1.52 1997/11/11 11:34:59 master Exp $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_xio_c =
!  *   "$Id: xio.c,v 1.53 1998/04/12 22:01:00 master Exp master $";
   */
  
  /*
***************
*** 39,44 ****
--- 39,45 ----
  #include <skills.h>
  #include <object.h>
  #include <stdarg.h>
+ #include <living.h>
  
  static char font_text_stats[]="8x13";
  static char font_text_info[]="8x13";
***************
*** 954,967 ****
      p->scroll_inv=0;
    if(p->last_weight!=pl->weight+pl->carrying) {
      p->last_weight=pl->weight+pl->carrying;
!     sprintf(buf,"Inventory%s: (%s)",
              (p->show_what == show_applied ? " (applied) " :
              (p->show_what == show_unapplied ? " (unapplied) " : 
  	    (p->show_what == show_unpaid ? " (unpaid) " :
  	    (p->show_what == show_cursed ? " (cursed) ": 
  	    (p->show_what == show_magical ? " (magical) " :
  	    (p->show_what == show_nonmagical ? " (nonmagical) " : "")))))),
!             query_weight(pl));
      XDrawImageString(p->gdisp,p->win_inv,
                       p->gc_inv_text,8,13,buf,strlen(buf));
    }
--- 955,968 ----
      p->scroll_inv=0;
    if(p->last_weight!=pl->weight+pl->carrying) {
      p->last_weight=pl->weight+pl->carrying;
!     sprintf(buf,"Inventory%s: (%s/%d)",
              (p->show_what == show_applied ? " (applied) " :
              (p->show_what == show_unapplied ? " (unapplied) " : 
  	    (p->show_what == show_unpaid ? " (unpaid) " :
  	    (p->show_what == show_cursed ? " (cursed) ": 
  	    (p->show_what == show_magical ? " (magical) " :
  	    (p->show_what == show_nonmagical ? " (nonmagical) " : "")))))),
!             query_weight(pl), weight_limit[pl->stats.Str]/1000);
      XDrawImageString(p->gdisp,p->win_inv,
                       p->gc_inv_text,8,13,buf,strlen(buf));
    }
*** crossfire-0.94.0//crossedit/Imakefile	Sun Feb  8 05:26:21 1998
--- crossfire-0.94.1/crossedit/Imakefile	Sun Apr 12 21:25:54 1998
***************
*** 1,5 ****
  /*
!  * $Id: Imakefile,v 1.3 1998/01/05 10:31:25 master Exp master $
   *
   * CrossEdit - Game world editor
   * Copyright (C) 1993 Petri Heinila & Jarkko Sonninen
--- 1,5 ----
  /*
!  * $Id: Imakefile,v 1.3 1998/01/05 10:31:25 master Exp $
   *
   * CrossEdit - Game world editor
   * Copyright (C) 1993 Petri Heinila & Jarkko Sonninen
*** crossfire-0.94.0//include/config.h	Sun Feb  8 05:26:21 1998
--- crossfire-0.94.1/include/config.h	Sun Apr 12 21:27:02 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_config_h =
!  *   "$Id: config.h,v 1.55 1998/02/08 01:02:59 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_config_h =
!  *   "$Id: config.h,v 1.55 1998/02/08 01:02:59 master Exp $";
   */
  
  /*
*** crossfire-0.94.0//include/define.h	Sun Feb  8 05:26:21 1998
--- crossfire-0.94.1/include/define.h	Sun Apr 12 21:27:27 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_define_h =
!  *   "$Id: define.h,v 1.56 1997/11/11 11:17:03 master Exp $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_define_h =
!  *   "$Id: define.h,v 1.57 1998/04/12 21:27:02 master Exp master $";
   */
  
  /*
***************
*** 727,729 ****
--- 727,732 ----
          } \
        strcat(retbuf,")"); \
      }
+ 
+ #define AP_APPLY 1
+ #define AP_UNAPPLY 2
*** crossfire-0.94.0//include/funcpoint.h	Sun Feb  8 05:26:21 1998
--- crossfire-0.94.1/include/funcpoint.h	Sun Apr 12 21:28:39 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_funcpoint_h =
!  *   "$Id: funcpoint.h,v 1.12 1998/02/08 01:06:04 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_funcpoint_h =
!  *   "$Id: funcpoint.h,v 1.13 1998/04/12 21:27:30 master Exp master $";
   */
  
  /*
***************
*** 27,38 ****
      This file was made after an idea by vidarl@ifi.uio.no
  */
  
  /*
   * These function-pointers are defined in common/glue.c
   * The functions used to set and initialise them are also there.
   */
  
! extern int	(*apply_func)			(object *, object *);
  extern void	(*draw_func)			(object *);
  extern void	(*draw_info_func)		(int, int, object *, const char *);
  extern void	(*draw_inventory_faces_func)	(object *);
--- 27,61 ----
      This file was made after an idea by vidarl@ifi.uio.no
  */
  
+ #ifndef FUNCPOINT_H
+ #define FUNCPOINT_H
+ 
+ /*
+  * Some function types
+  */
+ typedef void (*type_func_int)(int);
+ typedef void (*type_func_int_int)(int,int);
+ typedef void (*type_func_void)(void);
+ typedef void (*type_func_map)(mapstruct *);
+ typedef void (*type_func_map_char)(mapstruct *, char *);
+ typedef void (*type_func_int_map_char)(int, mapstruct *, char *);
+ typedef void (*type_func_ob)(object *);
+ typedef void (*type_func_ob_char)(object *, char *);
+ typedef void (*type_func_ob_cchar)(object *, const char *);
+ typedef void (*type_func_int_int_ob_cchar)(int, int, object *, const char *);
+ typedef void (*type_func_ob_ob)(object *, object *);
+ typedef void (*type_func_ob_int)(object *, int);
+ typedef int (*type_int_func_ob_ob)(object *, object *);
+ typedef void (*type_func_char_int)(char *, int);
+ typedef void (*type_func_int_ob_ob)(int, object *, object *);
+ typedef int (*type_int_func_ob_ob_int)(object *, object *,int);
+ 
  /*
   * These function-pointers are defined in common/glue.c
   * The functions used to set and initialise them are also there.
   */
  
! extern int	(*apply_func)			(object *, object *, int);
  extern void	(*draw_func)			(object *);
  extern void	(*draw_info_func)		(int, int, object *, const char *);
  extern void	(*draw_inventory_faces_func)	(object *);
***************
*** 43,49 ****
  extern void	(*emergency_save_func)		(int);
  extern void	(*fix_auto_apply_func)		(mapstruct *);
  extern void	(*init_blocksview_players_func)	();
! extern object *	(*monster_check_apply_func)	(object *, object *);
  extern void	(*process_active_maps_func)	();
  extern void	(*remove_friendly_object_func)	(object *);
  extern void	(*update_buttons_func)		(mapstruct *);
--- 66,72 ----
  extern void	(*emergency_save_func)		(int);
  extern void	(*fix_auto_apply_func)		(mapstruct *);
  extern void	(*init_blocksview_players_func)	();
! extern void	(*monster_check_apply_func)	(object *, object *);
  extern void	(*process_active_maps_func)	();
  extern void	(*remove_friendly_object_func)	(object *);
  extern void	(*update_buttons_func)		(mapstruct *);
***************
*** 54,56 ****
--- 77,82 ----
  extern void	(*esrv_send_item_func)		(object *, object *);
  extern void	(*esrv_del_item_func)		(int, int);
  extern void	(*esrv_update_item_func)	(int, object *, object *);
+ 
+ 
+ #endif
*** crossfire-0.94.0//include/global.h	Sun Feb  8 05:26:21 1998
--- crossfire-0.94.1/include/global.h	Sun Apr 12 21:28:51 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_global_h =
!  *   "$Id: global.h,v 1.36 1998/02/08 01:31:45 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_global_h =
!  *   "$Id: global.h,v 1.37 1998/04/12 21:28:40 master Exp master $";
   */
  
  /*
***************
*** 48,53 ****
--- 48,56 ----
  
  
  #include "structs.h"
+ 
+ #include "funcpoint.h"
+ 
  #if defined(RPLAY_SOUND) && !defined(__CEXTRACT__)
  #include <rplay.h> /* RPLAY structure */
  #endif
*** crossfire-0.94.0//include/libproto.h	Sun Feb  8 05:26:21 1998
--- crossfire-0.94.1/include/libproto.h	Sun Mar  8 11:06:13 1998
***************
*** 2,8 ****
   *   This file was automatically generated by version 1.7 of cextract.
   *   Manual editing not recommended.
   *
!  *   Created: Fri Jan 16 22:14:06 1998
   */
  #ifndef __CEXTRACT__
  #ifdef __STDC__
--- 2,8 ----
   *   This file was automatically generated by version 1.7 of cextract.
   *   Manual editing not recommended.
   *
!  *   Created: Sun Mar  8 03:06:13 1998
   */
  #ifndef __CEXTRACT__
  #ifdef __STDC__
***************
*** 106,111 ****
--- 106,112 ----
  extern int dummy_function_ob2int ( object *ob, object *ob2 );
  extern void dummy_function_ob_int ( object *ob, int i );
  extern void dummy_function_txtnr ( char *txt, int nr );
+ extern int dummy_int_function_ob_ob_int ( object *ob, object *ob2, int n );
  extern void dump_abilities ( void );
  extern void dump_alchemy ( void );
  extern void dump_all_archetypes ( void );
***************
*** 196,202 ****
  extern recipelist * get_random_recipelist ( void );
  extern godlink * get_rand_god ( void );
  extern object *get_split_ob ( object *orig_ob, int nr );
- extern int get_variable ( char *name );
  extern void give_artifact_abilities ( object *op, object *artifct );
  extern char *god_info_msg ( int level, int booksize );
  extern unsigned long hasharch ( char *str, int tablesize );
--- 197,202 ----
***************
*** 232,241 ****
  extern int is_magical ( object *op );
  extern object *is_player_inv ( object *op );
  extern long level_exp ( int level, double expmul );
  extern int light_not_listed ( object *op );
- extern object *LoadObject ( FILE *fp, char *inbuf );
  extern void load_archetypes ( void );
! extern int load_object ( FILE *fp, object *op );
  extern void load_objects ( mapstruct *m, FILE *fp, int block );
  extern mapstruct *load_original_map ( char *filename, int block );
  extern void load_treasures ( void );
--- 232,241 ----
  extern int is_magical ( object *op );
  extern object *is_player_inv ( object *op );
  extern long level_exp ( int level, double expmul );
+ extern int lex_load ( object *op );
  extern int light_not_listed ( object *op );
  extern void load_archetypes ( void );
! extern int load_object ( FILE *fp, object *op, int bufstate );
  extern void load_objects ( mapstruct *m, FILE *fp, int block );
  extern mapstruct *load_original_map ( char *filename, int block );
  extern void load_treasures ( void );
***************
*** 311,317 ****
  extern long seconds ( void );
  extern void second_arch_pass ( FILE *fp );
  extern void set_abs_magic ( object *op, int magic );
! extern void set_apply ( type_int_func_ob_ob addr );
  extern void set_attr_value ( living *stats, int attr, signed char value );
  extern void set_block ( int x, int y, int bx, int by );
  extern void set_cheat ( object *op );
--- 311,317 ----
  extern long seconds ( void );
  extern void second_arch_pass ( FILE *fp );
  extern void set_abs_magic ( object *op, int magic );
! extern void set_apply ( type_int_func_ob_ob_int addr );
  extern void set_attr_value ( living *stats, int attr, signed char value );
  extern void set_block ( int x, int y, int bx, int by );
  extern void set_cheat ( object *op );
***************
*** 377,382 ****
--- 377,385 ----
  extern int wall ( mapstruct *m, int x, int y );
  extern void write_book_archive ( void );
  extern struct xdirect *xreaddir ( XDIR *dir_ptr, int mask );
+ extern int yyerror ( char *s );
+ extern void yyrestart ( FILE *input_file );
+ extern void yy_load_buffer_state ( void );
  
  #endif /* __STDC__ */
  #endif /* __CEXTRACT__ */
*** crossfire-0.94.0//include/living.h	Sun Feb  8 05:26:21 1998
--- crossfire-0.94.1/include/living.h	Sun Apr 12 21:29:09 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_living_h =
!  *   "$Id: living.h,v 1.20 1997/01/05 09:58:46 master Exp $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_living_h =
!  *   "$Id: living.h,v 1.21 1998/04/12 21:28:56 master Exp master $";
   */
  
  /*
***************
*** 54,56 ****
--- 54,57 ----
  extern char *short_stat_name[7];
  extern char *lose_msg[7];
  extern float speed_bonus[MAX_STAT + 1];
+ extern int weight_limit[MAX_STAT + 1];
*** crossfire-0.94.0//include/loader.h	Sun Feb  8 05:26:21 1998
--- crossfire-0.94.1/include/loader.h	Sun Apr 12 21:30:04 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_object_h =
!  *   "$Id: loader.h,v 1.28 1997/01/05 09:58:53 master Exp $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_object_h =
!  *   "$Id: loader.h,v 1.29 1998/04/12 21:29:09 master Exp master $";
   */
  
  /*
***************
*** 59,69 ****
    V_IS_WOODED,V_IS_HILLY,V_HAS_READY_SKILL,V_HAS_READY_WEAPON,
    V_NO_SKILL_IDENT,V_GLOW_RADIUS,V_BLIND,V_SEE_IN_DARK,
    V_IS_CAULDRON,V_RANDOMITEMS,V_DUST,V_NO_STEAL,
- #ifdef NPCPROG
-   V_NPC_STATUS,V_NPC_PROGRAM,
- #endif
    NR_OF_VARIABLES
  };
  
  extern char *variables[NR_OF_VARIABLES];
  
--- 59,77 ----
    V_IS_WOODED,V_IS_HILLY,V_HAS_READY_SKILL,V_HAS_READY_WEAPON,
    V_NO_SKILL_IDENT,V_GLOW_RADIUS,V_BLIND,V_SEE_IN_DARK,
    V_IS_CAULDRON,V_RANDOMITEMS,V_DUST,V_NO_STEAL,
    NR_OF_VARIABLES
  };
+ 
+ #define LL_IGNORED  -1
+ #define LL_EOF	    0
+ #define LL_MORE	    1
+ #define LL_NORMAL   2
+ 
+ /* see loader.l for more details on this */
+ #define LO_REPEAT   0
+ #define LO_LINEMODE 1
+ #define LO_NEWFILE  2
+ #define	LO_NOREAD   3
  
  extern char *variables[NR_OF_VARIABLES];
  
*** crossfire-0.94.0//include/newclient.h	Sun Feb  8 05:26:21 1998
--- crossfire-0.94.1/include/newclient.h	Sun Apr 12 21:30:17 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_newclient_h =
!  *   "$Id: newclient.h,v 1.8 1998/02/08 01:32:11 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_newclient_h =
!  *   "$Id: newclient.h,v 1.9 1998/04/12 21:30:05 master Exp master $";
   */
  
  /*
***************
*** 97,102 ****
--- 97,103 ----
  #define CS_STAT_GRACE	23
  #define CS_STAT_MAXGRACE	24
  #define CS_STAT_FLAGS	25
+ #define CS_STAT_WEIGHT_LIM	26
  
  /* These are used with CS_STAT_FLAGS above to communicate S->C what the
   * server thinks the fireon & runon states are.
*** crossfire-0.94.0//include/patchlevel.h	Sun Feb  8 05:26:21 1998
--- crossfire-0.94.1/include/patchlevel.h	Sun Apr 12 22:07:42 1998
***************
*** 1,5 ****
  #ifdef MAKE
! #define PatchLevel .0
  #else
! #define PATCH ".0"
  #endif
--- 1,5 ----
  #ifdef MAKE
! #define PatchLevel .1
  #else
! #define PATCH ".1"
  #endif
*** crossfire-0.94.0//include/sproto.h	Sun Feb  8 05:26:21 1998
--- crossfire-0.94.1/include/sproto.h	Sun Mar  8 10:46:13 1998
***************
*** 2,8 ****
   *   This file was automatically generated by version 1.7 of cextract.
   *   Manual editing not recommended.
   *
!  *   Created: Sun Feb  1 20:49:27 1998
   */
  #ifndef __CEXTRACT__
  #ifdef __STDC__
--- 2,8 ----
   *   This file was automatically generated by version 1.7 of cextract.
   *   Manual editing not recommended.
   *
!  *   Created: Sun Mar  8 02:46:13 1998
   */
  #ifndef __CEXTRACT__
  #ifdef __STDC__
***************
*** 36,44 ****
  extern int esrv_apply_container ( object *op, object *sack );
  extern char *gravestone_text ( object *op );
  extern int make_gravestone ( object *op, object *grave );
! extern int apply ( object *op, object *tmp );
  extern void apply_below ( object *op );
! extern int apply_special ( object *who, object *op );
  extern int auto_apply ( object *op );
  extern void fix_auto_apply ( mapstruct *m );
  extern void eat_special_food ( object *who, object *food );
--- 36,44 ----
  extern int esrv_apply_container ( object *op, object *sack );
  extern char *gravestone_text ( object *op );
  extern int make_gravestone ( object *op, object *grave );
! extern int apply ( object *op, object *tmp, int mode );
  extern void apply_below ( object *op );
! extern int apply_special ( object *who, object *op, int aflags );
  extern int auto_apply ( object *op );
  extern void fix_auto_apply ( mapstruct *m );
  extern void eat_special_food ( object *who, object *food );
***************
*** 190,218 ****
  extern int parse_command ( object *op, char *str );
  extern FILE *BecomeDaemon ( char *filename );
  extern int apply_power_crystal ( object *op, object *crystal );
! extern void Send_With_Handling ( int cnum, SockList *msg );
! extern void Write_String_To_Socket ( int cnum, char *buf, int len );
! extern int getcnum ( uint32 client_id );
! extern void esrv_ToggleSound ( object *pl, int client_num );
! extern void esrv_play_sound ( object *pl, int soundnum, int x, int y );
! extern void MapRedrawCmd ( uint8 *buff, int len, int clientnum );
! extern void SendFaceCmd ( uint8 *buff, int len, int clientnum );
! extern void read_client_images ( void );
  extern void init_ericserver ( void );
! extern void HandleClient ( int cnum );
! extern void doeric_server ( void );
! extern int ericfd ( void );
  extern void esrv_remove_player ( long client_id );
  extern void send_query ( long client_id, uint8 flags, char *text );
! extern void esrv_print_msg ( uint32 client_id, int color, const char *str );
! extern void esrv_update_stats ( long client_id, object *pl );
! extern void esrv_new_player ( long client_id, long tag, char *name, long weight, long face );
! extern void esrv_del_item ( int client_id, int tag );
! extern void esrv_send_animation ( uint32 client_num, short anim_num );
  extern void esrv_send_face ( uint32 client_num, short face_num, int nocache );
  extern void draw_client_map ( object *pl );
  extern void esrv_map_scroll ( long client_id, int dx, int dy );
  extern void free_all_ericserver ( void );
  extern char *spool ( char *bp, char *error );
  extern void copy_score ( score *sc1, score *sc2 );
  extern char *put_score ( score *sc );
--- 190,213 ----
  extern int parse_command ( object *op, char *str );
  extern FILE *BecomeDaemon ( char *filename );
  extern int apply_power_crystal ( object *op, object *crystal );
! extern void esrv_del_item ( int client_id, int tag );
  extern void init_ericserver ( void );
! extern void esrv_new_player ( long client_id, long tag, char *name, long weight, long face );
  extern void esrv_remove_player ( long client_id );
+ extern void doeric_server ( void );
  extern void send_query ( long client_id, uint8 flags, char *text );
! extern int getcnum ( uint32 client_id );
  extern void esrv_send_face ( uint32 client_num, short face_num, int nocache );
+ extern void Send_With_Handling ( int cnum, SockList *msg );
+ extern int ericfd ( void );
+ extern void esrv_update_stats ( long client_id, object *pl );
+ extern void esrv_print_msg ( uint32 client_id, int color, const char *str );
  extern void draw_client_map ( object *pl );
  extern void esrv_map_scroll ( long client_id, int dx, int dy );
  extern void free_all_ericserver ( void );
+ extern void esrv_ToggleSound ( object *pl, int client_num );
+ extern void esrv_play_sound ( object *pl, int soundnum, int x, int y );
+ extern void HandleClient ( int cnum );
  extern char *spool ( char *bp, char *error );
  extern void copy_score ( score *sc1, score *sc2 );
  extern char *put_score ( score *sc );
***************
*** 427,437 ****
  extern int try_fit ( object *op, int x, int y );
  extern int roll_ob ( object *op, int dir, object *pusher );
  extern int push_ob ( object *who, int dir, object *pusher );
! extern unsigned int query_flags ( object *op );
! extern void esrv_draw_look ( object *pl );
  extern void esrv_send_inventory ( object *pl, object *op );
  extern void esrv_update_item ( int flags, object *pl, object *op );
- extern void esrv_send_item ( object *pl, object*op );
  extern obwin *get_empty_obwin ( void );
  extern void resize_obwin ( obwin *o, int width, int height );
  extern obwin * create_obwin ( player *p, int x, int y, int width, int height, int standalone, char *name );
--- 422,431 ----
  extern int try_fit ( object *op, int x, int y );
  extern int roll_ob ( object *op, int dir, object *pusher );
  extern int push_ob ( object *who, int dir, object *pusher );
! extern void esrv_send_item ( object *pl, object*op );
  extern void esrv_send_inventory ( object *pl, object *op );
+ extern void esrv_draw_look ( object *pl );
  extern void esrv_update_item ( int flags, object *pl, object *op );
  extern obwin *get_empty_obwin ( void );
  extern void resize_obwin ( obwin *o, int width, int height );
  extern obwin * create_obwin ( player *p, int x, int y, int width, int height, int standalone, char *name );
*** crossfire-0.94.0//include/structs.h	Sun Feb  8 05:26:21 1998
--- crossfire-0.94.1/include/structs.h	Sun Apr 12 21:31:34 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_structs_h =
!  *   "$Id: structs.h,v 1.61 1998/02/08 01:35:50 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_structs_h =
!  *   "$Id: structs.h,v 1.62 1998/04/12 21:30:24 master Exp master $";
   */
  
  /*
***************
*** 219,228 ****
  /* Some debug variables: */
    unsigned short run_away;	/* Monster runs away if it's hp goes below \
  				   this percentage. */
- #ifdef NPC_PROG
-   unsigned short npc_status;	/* What the NPC is doing right now */
-   unsigned short npc_program;	/* Helps find out what the NPC will do next */
- #endif
   
  /* Not commented out by ALLOW_SKILLS - to many pieces of code want this
   * information
--- 219,224 ----
***************
*** 467,472 ****
--- 463,469 ----
    float last_weapon_sp;    /* Last turn */
    signed char last_armour; /* Last turn */
    uint16 last_flags;	    /* fire/run on flags for last tick */
+     uint32  last_weight_limit;	/* Last weight limit transmitted to client */
    char **menu_strings;
    uint16 menu_items_num;
    uint16 menu_on_item;
***************
*** 887,911 ****
   * contents of a shared_string, look in shstr.h
   */
  typedef int shared_string;
- 
- /*
-  * Some function types
-  */
- typedef void (*type_func_int)(int);
- typedef void (*type_func_int_int)(int,int);
- typedef void (*type_func_void)(void);
- typedef void (*type_func_map)(mapstruct *);
- typedef void (*type_func_map_char)(mapstruct *, char *);
- typedef void (*type_func_int_map_char)(int, mapstruct *, char *);
- typedef void (*type_func_ob)(object *);
- typedef void (*type_func_ob_char)(object *, char *);
- typedef void (*type_func_ob_cchar)(object *, const char *);
- typedef void (*type_func_int_int_ob_cchar)(int, int, object *, const char *);
- typedef void (*type_func_ob_ob)(object *, object *);
- typedef void (*type_func_ob_int)(object *, int);
- typedef int (*type_int_func_ob_ob)(object *, object *);
- typedef void (*type_func_char_int)(char *, int);
- typedef void (*type_func_int_ob_ob)(int, object *, object *);
  
  #endif /* STRUCTS_H */
  
--- 884,889 ----
*** crossfire-0.94.0//include/version.h	Sun Feb  8 05:26:21 1998
--- crossfire-0.94.1/include/version.h	Sun Apr 12 21:31:34 1998
***************
*** 1,6 ****
  /*
   * static char *rcsid_version_h =
!  *   "$Id: version.h,v 1.7 1998/02/08 01:36:41 master Exp master $";
   */
  
  /*
--- 1,6 ----
  /*
   * static char *rcsid_version_h =
!  *   "$Id: version.h,v 1.7 1998/02/08 01:36:41 master Exp $";
   */
  
  /*
*** crossfire-0.94.0//config/crosssite.def	Sun Feb  8 05:26:21 1998
--- crossfire-0.94.1/config/crosssite.def	Sun Apr 12 21:23:03 1998
***************
*** 154,159 ****
--- 154,163 ----
   * Changed name from SoundEffects to Rplay_Sound since that is more
   * descriptive.  The new client will get sound effects regardless of this
   * setting - it uses a mechanism other than the rplay library.
+  *
+  * Note - selecting this will result in various warning about RPLAY_SOUND
+  * being redefined.  Being this feature will be depreciated in the not
+  * too distant future, it probably isn't worth fixing here.
   */
  
  /*
***************
*** 217,224 ****
  /* DEBUG_DMALLOC tells it to use the dmalloc package.  This is a publically
   * available package that can be installed on most any system.
   */
! #define DEBUG_DMALLOC
  /*
  #define DEBUG_MALLOC_LEVEL	1
  */
  
--- 221,229 ----
  /* DEBUG_DMALLOC tells it to use the dmalloc package.  This is a publically
   * available package that can be installed on most any system.
   */
! 
  /*
+ #define DEBUG_DMALLOC
  #define DEBUG_MALLOC_LEVEL	1
  */
  
*** crossfire-0.94.0//config/master-site.def	Sun Feb  8 05:26:21 1998
--- crossfire-0.94.1/config/master-site.def	Sun Apr 12 21:22:40 1998
***************
*** 150,159 ****
   * Changed name from SoundEffects to Rplay_Sound since that is more
   * descriptive.  The new client will get sound effects regardless of this
   * setting - it uses a mechanism other than the rplay library.
   */
  
  
! #define Rplay_Sound
  #define RPlayLibDir /usr/local/lib
  #define RPlayIncDir /usr/local/include
  
--- 150,163 ----
   * Changed name from SoundEffects to Rplay_Sound since that is more
   * descriptive.  The new client will get sound effects regardless of this
   * setting - it uses a mechanism other than the rplay library.
+  *
+  * Note - selecting this will result in various warning about RPLAY_SOUND
+  * being redefined.  Being this feature will be depreciated in the not
+  * too distant future, it probably isn't worth fixing here.
   */
  
  
! /*#define Rplay_Sound*/
  #define RPlayLibDir /usr/local/lib
  #define RPlayIncDir /usr/local/include
  
***************
*** 206,213 ****
   * (this is SLOW.)
   * read the malloc man page for more information
   */
- #define DEBUG_MALLOC
  
  /* DEBUG_DMALLOC tells it to use the dmalloc package.  This is a publically
   * available package that can be installed on most any system.
   */
--- 210,219 ----
   * (this is SLOW.)
   * read the malloc man page for more information
   */
  
+ /*
+ #define DEBUG_MALLOC
+ */
  /* DEBUG_DMALLOC tells it to use the dmalloc package.  This is a publically
   * available package that can be installed on most any system.
   */
*** crossfire-0.94.0//lib/artifacts	Sun Feb  8 05:26:22 1998
--- crossfire-0.94.1/lib/artifacts	Tue Feb 17 10:39:04 1998
***************
*** 79,84 ****
--- 79,88 ----
  # value in order to the object to be created.  This can make it so that
  # some items are never created on easy maps.
  #
+ # Note that the above mentioned fields (chance, difficulty) must be set
+ # before the Object command - if they are placed between the Object and
+ # End commands, they will have no affect.
+ #
  # Because of these changes, general artifact types are no longer allowed.
  # This is for a few reasons: 1) With no type, it would not be possible
  # to know what lists to put it on.  If it put it on all lists
***************
*** 2118,2125 ****
  #
  Allowed talisman
  chance 20
- Object Evocation
  difficulty 10
  type 43
  value 9
  path_attuned 6208
--- 2122,2129 ----
  #
  Allowed talisman
  chance 20
  difficulty 10
+ Object Evocation
  type 43
  value 9
  path_attuned 6208
***************
*** 2127,2134 ****
  #
  Allowed talisman
  chance 20
- Object Elements
  difficulty 10
  type 43
  value 9
  path_attuned 14
--- 2131,2138 ----
  #
  Allowed talisman
  chance 20
  difficulty 10
+ Object Elements
  type 43
  value 9
  path_attuned 14
***************
*** 2136,2144 ****
  #
  Allowed talisman
  chance 3
  Object Wizardry
  type 43
- difficulty 13
  value 25
  path_attuned 28286
  Pow 1
--- 2140,2148 ----
  #
  Allowed talisman
  chance 3
+ difficulty 13
  Object Wizardry
  type 43
  value 25
  path_attuned 28286
  Pow 1
***************
*** 2148,2156 ****
  #
  Allowed holy_symbol
  chance 80
  Object Probity
  type 43
- difficulty 5
  value 5
  path_attuned 257
  path_repelled 128
--- 2152,2160 ----
  #
  Allowed holy_symbol
  chance 80
+ difficulty 5
  Object Probity
  type 43
  value 5
  path_attuned 257
  path_repelled 128
***************
*** 2159,2167 ****
  #
  Allowed holy_symbol
  chance 10
  Object Great Virtue
  type 43
- difficulty 5
  value 25
  path_attuned 8640
  Wis 2
--- 2163,2171 ----
  #
  Allowed holy_symbol
  chance 10
+ difficulty 5
  Object Great Virtue
  type 43
  value 25
  path_attuned 8640
  Wis 2
***************
*** 2169,2177 ****
  #
  Allowed holy_symbol
  chance 50
  Object Calling
  type 43
- difficulty 5
  value 5
  path_attuned 64
  path_repelled 256
--- 2173,2181 ----
  #
  Allowed holy_symbol
  chance 50
+ difficulty 5
  Object Calling
  type 43
  value 5
  path_attuned 64
  path_repelled 256
***************
*** 2189,2226 ****
  #
  Allowed water
  chance 15
  Object emerald
  type 54
  food 1
  value 58
- difficulty 3
  end
  #
  Allowed water
  chance 13
  Object sapphire
  type 54
  food 1
  value 67
- difficulty 5
  end
  #
  Allowed water
  chance 8
  Object ruby
  type 54
  food 1
  value 76
- difficulty 5
  end
  #
  Allowed water
  chance 3
  Object diamond
  type 54
  food 1
  value 191
- difficulty 8
  end
  #
  #
--- 2193,2230 ----
  #
  Allowed water
  chance 15
+ difficulty 3
  Object emerald
  type 54
  food 1
  value 58
  end
  #
  Allowed water
  chance 13
+ difficulty 5
  Object sapphire
  type 54
  food 1
  value 67
  end
  #
  Allowed water
  chance 8
+ difficulty 5
  Object ruby
  type 54
  food 1
  value 76
  end
  #
  Allowed water
  chance 3
+ difficulty 8
  Object diamond
  type 54
  food 1
  value 191
  end
  #
  #
*** crossfire-0.94.0//lib/treasures	Sun Feb  8 05:26:22 1998
--- crossfire-0.94.1/lib/treasures	Mon Mar  9 02:35:10 1998
***************
*** 1069,1074 ****
--- 1069,1077 ----
    list uncommon_items
      magic 8
      chance 5
+   more
+   arch ring_nodrain
+     chance 5
    end
  treasureone containers
    arch sack
***************
*** 1348,1356 ****
      chance 5
    more
    arch dragon_shield
-     chance 5
-   more
-   arch ring_nodrain
      chance 5
    more
    arch helmet_of_xrays
--- 1351,1356 ----
*** crossfire-0.94.0//lib/help/apply	Sun Feb  8 05:26:27 1998
--- crossfire-0.94.1/lib/help/apply	Sun Mar  8 10:29:03 1998
***************
*** 3,7 ****
  If no options are given, it applies
  an object you are standing on.
  
! If any option is given, it applies the 
! first item in your inventory.
--- 3,14 ----
  If no options are given, it applies
  an object you are standing on.
  
! If an object name is given, it
! will apply/unapply that object (toggle)
! 
! Extra options to apply:
! -a: Always applies the object
! -u: Always unapplies the object.
! 
!  These two options disable the
! toggling feature.
