Mercurial > hg > early-roguelike
diff arogue7/state.c @ 125:adfa37e67084
Import Advanced Rogue 7.7 from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Fri, 08 May 2015 15:24:40 -0400 |
parents | |
children | b786053d2f37 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arogue7/state.c Fri May 08 15:24:40 2015 -0400 @@ -0,0 +1,2674 @@ +/* + state.c - Portable Rogue Save State Code + + Copyright (C) 1999, 2000, 2005 Nicholas J. Kisseberth + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name(s) of the author(s) nor the names of other contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +*/ + +/************************************************************************/ +/* Save State Code */ +/************************************************************************/ + +#define RSID_STATS 0xABCD0001 +#define RSID_MSTATS 0xABCD0002 +#define RSID_THING 0xABCD0003 +#define RSID_OBJECT 0xABCD0004 +#define RSID_MAGICITEMS 0xABCD0005 +#define RSID_KNOWS 0xABCD0006 +#define RSID_GUESSES 0xABCD0007 +#define RSID_OBJECTLIST 0xABCD0008 +#define RSID_BAGOBJECT 0xABCD0009 +#define RSID_MONSTERLIST 0xABCD000A +#define RSID_MONSTERSTATS 0xABCD000B +#define RSID_MONSTERS 0xABCD000C +#define RSID_TRAP 0xABCD000D +#define RSID_WINDOW 0xABCD000E +#define RSID_DAEMONS 0xABCD000F +#define RSID_STICKS 0xABCD0010 +#define RSID_IARMOR 0xABCD0011 +#define RSID_SPELLS 0xABCD0012 +#define RSID_ILIST 0xABCD0013 +#define RSID_HLIST 0xABCD0014 +#define RSID_DEATHTYPE 0xABCD0015 +#define RSID_CTYPES 0XABCD0016 +#define RSID_COORDLIST 0XABCD0017 +#define RSID_ROOMS 0XABCD0018 + +#include <curses.h> +#include <stdio.h> +#include <stdlib.h> +#include "rogue.h" + +#define READSTAT (format_error || read_error ) +#define WRITESTAT (write_error) + +static int read_error = FALSE; +static int write_error = FALSE; +static int format_error = FALSE; +static int endian = 0x01020304; +#define big_endian ( *((char *)&endian) == 0x01 ) + +int +rs_write(FILE *savef, void *ptr, size_t size) +{ + if (write_error) + return(WRITESTAT); + + if (encwrite(ptr, size, fileno(savef)) != size) + write_error = 1; + + return(WRITESTAT); +} + +int +rs_read(int inf, void *ptr, size_t size) +{ + if (read_error || format_error) + return(READSTAT); + + if (encread(ptr, size, inf) != size) + read_error = 1; + + return(READSTAT); +} + +int +rs_write_uchar(FILE *savef, unsigned char c) +{ + if (write_error) + return(WRITESTAT); + + rs_write(savef, &c, 1); + + return(WRITESTAT); +} + +int +rs_read_uchar(int inf, unsigned char *c) +{ + if (read_error || format_error) + return(READSTAT); + + rs_read(inf, c, 1); + + return(READSTAT); +} + +int +rs_write_char(FILE *savef, char c) +{ + if (write_error) + return(WRITESTAT); + + rs_write(savef, &c, 1); + + return(WRITESTAT); +} + +int +rs_read_char(int inf, char *c) +{ + if (read_error || format_error) + return(READSTAT); + + rs_read(inf, c, 1); + + return(READSTAT); +} + +int +rs_write_chars(FILE *savef, char *c, int count) +{ + if (write_error) + return(WRITESTAT); + + rs_write_int(savef, count); + rs_write(savef, c, count); + + return(WRITESTAT); +} + +int +rs_read_chars(int inf, char *i, int count) +{ + int value = 0; + + if (read_error || format_error) + return(READSTAT); + + rs_read_int(inf, &value); + + if (value != count) + format_error = TRUE; + + rs_read(inf, i, count); + + return(READSTAT); +} + +int +rs_write_int(FILE *savef, int c) +{ + unsigned char bytes[4]; + unsigned char *buf = (unsigned char *) &c; + + if (write_error) + return(WRITESTAT); + + if (big_endian) + { + bytes[3] = buf[0]; + bytes[2] = buf[1]; + bytes[1] = buf[2]; + bytes[0] = buf[3]; + buf = bytes; + } + + rs_write(savef, buf, 4); + + return(WRITESTAT); +} + +int +rs_read_int(int inf, int *i) +{ + unsigned char bytes[4]; + int input = 0; + unsigned char *buf = (unsigned char *)&input; + + if (read_error || format_error) + return(READSTAT); + + rs_read(inf, &input, 4); + + if (big_endian) + { + bytes[3] = buf[0]; + bytes[2] = buf[1]; + bytes[1] = buf[2]; + bytes[0] = buf[3]; + buf = bytes; + } + + *i = *((int *) buf); + + return(READSTAT); +} + +int +rs_write_ints(FILE *savef, int *c, int count) +{ + int n = 0; + + if (write_error) + return(WRITESTAT); + + rs_write_int(savef, count); + + for(n = 0; n < count; n++) + if( rs_write_int(savef,c[n]) != 0) + break; + + return(WRITESTAT); +} + +int +rs_read_ints(int inf, int *i, int count) +{ + int n, value; + + if (read_error || format_error) + return(READSTAT); + + rs_read_int(inf,&value); + + if (value != count) + format_error = TRUE; + + for(n = 0; n < count; n++) + if (rs_read_int(inf, &i[n]) != 0) + break; + + return(READSTAT); +} + +int +rs_write_boolean(FILE *savef, bool c) +{ + unsigned char buf = (c == 0) ? 0 : 1; + + if (write_error) + return(WRITESTAT); + + rs_write(savef, &buf, 1); + + return(WRITESTAT); +} + +int +rs_read_boolean(int inf, bool *i) +{ + unsigned char buf = 0; + + if (read_error || format_error) + return(READSTAT); + + rs_read(inf, &buf, 1); + + *i = (buf != 0); + + return(READSTAT); +} + +int +rs_write_booleans(FILE *savef, bool *c, int count) +{ + int n = 0; + + if (write_error) + return(WRITESTAT); + + rs_write_int(savef, count); + + for(n = 0; n < count; n++) + if (rs_write_boolean(savef, c[n]) != 0) + break; + + return(WRITESTAT); +} + +int +rs_read_booleans(int inf, bool *i, int count) +{ + int n = 0, value = 0; + + if (read_error || format_error) + return(READSTAT); + + rs_read_int(inf,&value); + + if (value != count) + format_error = TRUE; + + for(n = 0; n < count; n++) + if (rs_read_boolean(inf, &i[n]) != 0) + break; + + return(READSTAT); +} + +int +rs_write_short(FILE *savef, short c) +{ + unsigned char bytes[2]; + unsigned char *buf = (unsigned char *) &c; + + if (write_error) + return(WRITESTAT); + + if (big_endian) + { + bytes[1] = buf[0]; + bytes[0] = buf[1]; + buf = bytes; + } + + rs_write(savef, buf, 2); + + return(WRITESTAT); +} + +int +rs_read_short(int inf, short *i) +{ + unsigned char bytes[2]; + short input; + unsigned char *buf = (unsigned char *)&input; + + if (read_error || format_error) + return(READSTAT); + + rs_read(inf, &input, 2); + + if (big_endian) + { + bytes[1] = buf[0]; + bytes[0] = buf[1]; + buf = bytes; + } + + *i = *((short *) buf); + + return(READSTAT); +} + +int +rs_write_shorts(FILE *savef, short *c, int count) +{ + int n = 0; + + if (write_error) + return(WRITESTAT); + + rs_write_int(savef, count); + + for(n = 0; n < count; n++) + if (rs_write_short(savef, c[n]) != 0) + break; + + return(WRITESTAT); +} + +int +rs_read_shorts(int inf, short *i, int count) +{ + int n = 0, value = 0; + + if (read_error || format_error) + return(READSTAT); + + rs_read_int(inf,&value); + + if (value != count) + format_error = TRUE; + + for(n = 0; n < value; n++) + if (rs_read_short(inf, &i[n]) != 0) + break; + + return(READSTAT); +} + +int +rs_write_ushort(FILE *savef, unsigned short c) +{ + unsigned char bytes[2]; + unsigned char *buf = (unsigned char *) &c; + + if (write_error) + return(WRITESTAT); + + if (big_endian) + { + bytes[1] = buf[0]; + bytes[0] = buf[1]; + buf = bytes; + } + + rs_write(savef, buf, 2); + + return(WRITESTAT); +} + +int +rs_read_ushort(int inf, unsigned short *i) +{ + unsigned char bytes[2]; + unsigned short input; + unsigned char *buf = (unsigned char *)&input; + + if (read_error || format_error) + return(READSTAT); + + rs_read(inf, &input, 2); + + if (big_endian) + { + bytes[1] = buf[0]; + bytes[0] = buf[1]; + buf = bytes; + } + + *i = *((unsigned short *) buf); + + return(READSTAT); +} + +int +rs_write_uint(FILE *savef, unsigned int c) +{ + unsigned char bytes[4]; + unsigned char *buf = (unsigned char *) &c; + + if (write_error) + return(WRITESTAT); + + if (big_endian) + { + bytes[3] = buf[0]; + bytes[2] = buf[1]; + bytes[1] = buf[2]; + bytes[0] = buf[3]; + buf = bytes; + } + + rs_write(savef, buf, 4); + + return(WRITESTAT); +} + +int +rs_read_uint(int inf, unsigned int *i) +{ + unsigned char bytes[4]; + int input; + unsigned char *buf = (unsigned char *)&input; + + if (read_error || format_error) + return(READSTAT); + + rs_read(inf, &input, 4); + + if (big_endian) + { + bytes[3] = buf[0]; + bytes[2] = buf[1]; + bytes[1] = buf[2]; + bytes[0] = buf[3]; + buf = bytes; + } + + *i = *((unsigned int *) buf); + + return(READSTAT); +} + +int +rs_write_long(FILE *savef, long c) +{ + int c2; + unsigned char bytes[4]; + unsigned char *buf = (unsigned char *)&c; + + if (write_error) + return(WRITESTAT); + + if (sizeof(long) == 8) + { + c2 = c; + buf = (unsigned char *) &c2; + } + + if (big_endian) + { + bytes[3] = buf[0]; + bytes[2] = buf[1]; + bytes[1] = buf[2]; + bytes[0] = buf[3]; + buf = bytes; + } + + rs_write(savef, buf, 4); + + return(WRITESTAT); +} + +int +rs_read_long(int inf, long *i) +{ + unsigned char bytes[4]; + long input; + unsigned char *buf = (unsigned char *) &input; + + if (read_error || format_error) + return(READSTAT); + + rs_read(inf, &input, 4); + + if (big_endian) + { + bytes[3] = buf[0]; + bytes[2] = buf[1]; + bytes[1] = buf[2]; + bytes[0] = buf[3]; + buf = bytes; + } + + *i = *((long *) buf); + + return(READSTAT); +} + +int +rs_write_longs(FILE *savef, long *c, int count) +{ + int n = 0; + + if (write_error) + return(WRITESTAT); + + rs_write_int(savef,count); + + for(n = 0; n < count; n++) + rs_write_long(savef, c[n]); + + return(WRITESTAT); +} + +int +rs_read_longs(int inf, long *i, int count) +{ + int n = 0, value = 0; + + if (read_error || format_error) + return(READSTAT); + + rs_read_int(inf,&value); + + if (value != count) + format_error = TRUE; + + for(n = 0; n < value; n++) + if (rs_read_long(inf, &i[n]) != 0) + break; + + return(READSTAT); +} + +int +rs_write_ulong(FILE *savef, unsigned long c) +{ + unsigned int c2; + unsigned char bytes[4]; + unsigned char *buf = (unsigned char *)&c; + + if (write_error) + return(WRITESTAT); + + if ( (sizeof(long) == 8) && (sizeof(int) == 4) ) + { + c2 = c; + buf = (unsigned char *) &c2; + } + + if (big_endian) + { + bytes[3] = buf[0]; + bytes[2] = buf[1]; + bytes[1] = buf[2]; + bytes[0] = buf[3]; + buf = bytes; + } + + rs_write(savef, buf, 4); + + return(WRITESTAT); +} + +int +rs_read_ulong(int inf, unsigned long *i) +{ + unsigned char bytes[4]; + unsigned long input; + unsigned char *buf = (unsigned char *) &input; + + if (read_error || format_error) + return(READSTAT); + + rs_read(inf, &input, 4); + + if (big_endian) + { + bytes[3] = buf[0]; + bytes[2] = buf[1]; + bytes[1] = buf[2]; + bytes[0] = buf[3]; + buf = bytes; + } + + *i = *((unsigned long *) buf); + + return(READSTAT); +} + +int +rs_write_ulongs(FILE *savef, unsigned long *c, int count) +{ + int n = 0; + + if (write_error) + return(WRITESTAT); + + rs_write_int(savef,count); + + for(n = 0; n < count; n++) + if (rs_write_ulong(savef,c[n]) != 0) + break; + + return(WRITESTAT); +} + +int +rs_read_ulongs(int inf, unsigned long *i, int count) +{ + int n = 0, value = 0; + + if (read_error || format_error) + return(READSTAT); + + rs_read_int(inf,&value); + + if (value != count) + format_error = TRUE; + + for(n = 0; n < count; n++) + if (rs_read_ulong(inf, &i[n]) != 0) + break; + + return(READSTAT); +} + +int +rs_write_marker(FILE *savef, int id) +{ + if (write_error) + return(WRITESTAT); + + rs_write_int(savef, id); + + return(WRITESTAT); +} + +int +rs_read_marker(int inf, int id) +{ + int nid; + + if (read_error || format_error) + return(READSTAT); + + if (rs_read_int(inf, &nid) == 0) + if (id != nid) + format_error = 1; + + return(READSTAT); +} + + + +/******************************************************************************/ + +int +rs_write_string(FILE *savef, char *s) +{ + int len = 0; + + if (write_error) + return(WRITESTAT); + + len = (s == NULL) ? 0 : (int) strlen(s) + 1; + + rs_write_int(savef, len); + rs_write_chars(savef, s, len); + + return(WRITESTAT); +} + +int +rs_read_string(int inf, char *s, int max) +{ + int len = 0; + + if (read_error || format_error) + return(READSTAT); + + rs_read_int(inf, &len); + + if (len > max) + format_error = TRUE; + + rs_read_chars(inf, s, len); + + return(READSTAT); +} + +int +rs_read_new_string(int inf, char **s) +{ + int len=0; + char *buf=0; + + if (read_error || format_error) + return(READSTAT); + + rs_read_int(inf, &len); + + if (len == 0) + buf = NULL; + else + { + buf = malloc(len); + + if (buf == NULL) + read_error = TRUE; + } + + rs_read_chars(inf, buf, len); + + *s = buf; + + return(READSTAT); +} + +int +rs_write_strings(FILE *savef, char *s[], int count) +{ + int n = 0; + + if (write_error) + return(WRITESTAT); + + rs_write_int(savef, count); + + for(n = 0; n < count; n++) + if (rs_write_string(savef, s[n]) != 0) + break; + + return(WRITESTAT); +} + +int +rs_read_strings(int inf, char **s, int count, int max) +{ + int n = 0; + int value = 0; + + if (read_error || format_error) + return(READSTAT); + + rs_read_int(inf, &value); + + if (value != count) + format_error = TRUE; + + for(n = 0; n < count; n++) + if (rs_read_string(inf, s[n], max) != 0) + break; + + return(READSTAT); +} + +int +rs_read_new_strings(int inf, char **s, int count) +{ + int n = 0; + int value = 0; + + if (read_error || format_error) + return(READSTAT); + + rs_read_int(inf, &value); + + if (value != count) + format_error = TRUE; + + for(n = 0; n < count; n++) + if (rs_read_new_string(inf, &s[n]) != 0) + break; + + return(READSTAT); +} + +int +rs_write_string_index(FILE *savef, char *master[], int max, const char *str) +{ + int i; + + if (write_error) + return(WRITESTAT); + + for(i = 0; i < max; i++) + if (str == master[i]) + return( rs_write_int(savef, i) ); + + return( rs_write_int(savef,-1) ); +} + +int +rs_read_string_index(int inf, char *master[], int maxindex, char **str) +{ + int i; + + if (read_error || format_error) + return(READSTAT); + + rs_read_int(inf, &i); + + if (i > maxindex) + format_error = TRUE; + else if (i >= 0) + *str = master[i]; + else + *str = NULL; + + return(READSTAT); +} + +int +rs_write_coord(FILE *savef, coord c) +{ + if (write_error) + return(WRITESTAT); + + rs_write_int(savef, c.x); + rs_write_int(savef, c.y); + + return(WRITESTAT); +} + +int +rs_read_coord(int inf, coord *c) +{ + coord in; + + if (read_error || format_error) + return(READSTAT); + + rs_read_int(inf,&in.x); + rs_read_int(inf,&in.y); + + if (READSTAT == 0) + { + c->x = in.x; + c->y = in.y; + } + + return(READSTAT); +} + +int +rs_write_coord_list(FILE *savef, struct linked_list *l) +{ + rs_write_marker(savef, RSID_COORDLIST); + rs_write_int(savef, list_size(l)); + + while (l != NULL) + { + rs_write_coord(savef, *(coord *) l->l_data); + l = l->l_next; + } + + return(WRITESTAT); +} + +int +rs_read_coord_list(int inf, struct linked_list **list) +{ + int i, cnt; + struct linked_list *l = NULL, *previous = NULL, *head = NULL; + + rs_read_marker(inf, RSID_COORDLIST); + + if (rs_read_int(inf,&cnt) != 0) + return(READSTAT); + + for (i = 0; i < cnt; i++) + { + l = new_item(sizeof(coord)); + l->l_prev = previous; + + if (previous != NULL) + previous->l_next = l; + + rs_read_coord(inf,(coord *) l->l_data); + + if (previous == NULL) + head = l; + + previous = l; + } + + if (l != NULL) + l->l_next = NULL; + + *list = head; + + return(READSTAT); +} + +int +rs_write_window(FILE *savef, WINDOW *win) +{ + int row,col,height,width; + + if (write_error) + return(WRITESTAT); + + width = getmaxx(win); + height = getmaxy(win); + + rs_write_marker(savef,RSID_WINDOW); + rs_write_int(savef,height); + rs_write_int(savef,width); + + for(row=0;row<height;row++) + for(col=0;col<width;col++) + if (rs_write_int(savef, mvwinch(win,row,col)) != 0) + return(WRITESTAT); + + return(WRITESTAT); +} + +int +rs_read_window(int inf, WINDOW *win) +{ + int row,col,maxlines,maxcols,value,width,height; + + if (read_error || format_error) + return(READSTAT); + + width = getmaxx(win); + height = getmaxy(win); + + rs_read_marker(inf, RSID_WINDOW); + + rs_read_int(inf, &maxlines); + rs_read_int(inf, &maxcols); + + for(row = 0; row < maxlines; row++) + for(col = 0; col < maxcols; col++) + { + if (rs_read_int(inf, &value) != 0) + return(READSTAT); + + if ((row < height) && (col < width)) + mvwaddch(win,row,col,value); + } + + return(READSTAT); +} + +/******************************************************************************/ + +void * +get_list_item(struct linked_list *l, int i) +{ + int count; + + for(count = 0; l != NULL; count++, l = l->l_next) + if (count == i) + return(l->l_data); + + return(NULL); +} + +int +find_list_ptr(struct linked_list *l, void *ptr) +{ + int count; + + for(count = 0; l != NULL; count++, l = l->l_next) + if (l->l_data == ptr) + return(count); + + return(-1); +} + +int +list_size(struct linked_list *l) +{ + int count; + + for(count = 0; l != NULL; count++, l = l->l_next) + ; + + return(count); +} + +/******************************************************************************/ + +int +rs_write_levtype(FILE *savef, LEVTYPE c) +{ + int lt; + + switch(c) + { + case NORMLEV: lt = 1; break; + case POSTLEV: lt = 2; break; + case MAZELEV: lt = 3; break; + case OUTSIDE: lt = 4; break; + case STARTLEV: lt = 5; break; + default: lt = -1; break; + } + + rs_write_int(savef,lt); + + return(WRITESTAT); +} + +int +rs_read_levtype(int inf, LEVTYPE *l) +{ + int lt; + + rs_read_int(inf, <); + + switch(lt) + { + case 1: *l = NORMLEV; break; + case 2: *l = POSTLEV; break; + case 3: *l = MAZELEV; break; + case 4: *l = OUTSIDE; break; + case 5: *l = STARTLEV; break; + default: *l = NORMLEV; break; + } + + return(READSTAT); +} + +int +rs_write_stats(FILE *savef, struct stats *s) +{ + if (write_error) + return(WRITESTAT); + + rs_write_marker(savef, RSID_STATS); + rs_write_short(savef, s->s_str); + rs_write_short(savef, s->s_intel); + rs_write_short(savef, s->s_wisdom); + rs_write_short(savef, s->s_dext); + rs_write_short(savef, s->s_const); + rs_write_short(savef, s->s_charisma); + rs_write_ulong(savef, s->s_exp); + rs_write_int(savef, s->s_lvladj); + rs_write_int(savef, s->s_lvl); + rs_write_int(savef, s->s_arm); + rs_write_int(savef, s->s_hpt); + rs_write_int(savef, s->s_pack); + rs_write_int(savef, s->s_carry); + rs_write(savef, s->s_dmg, sizeof(s->s_dmg)); + + return(WRITESTAT); +} + +int +rs_read_stats(int inf, struct stats *s) +{ + if (read_error || format_error) + return(READSTAT); + + rs_read_marker(inf, RSID_STATS); + rs_read_short(inf,&s->s_str); + rs_read_short(inf,&s->s_intel); + rs_read_short(inf,&s->s_wisdom); + rs_read_short(inf,&s->s_dext); + rs_read_short(inf,&s->s_const); + rs_read_short(inf,&s->s_charisma); + rs_read_ulong(inf,&s->s_exp); + rs_read_int(inf,&s->s_lvladj); + rs_read_int(inf,&s->s_lvl); + rs_read_int(inf,&s->s_arm); + rs_read_int(inf,&s->s_hpt); + rs_read_int(inf,&s->s_pack); + rs_read_int(inf,&s->s_carry); + rs_read(inf,s->s_dmg,sizeof(s->s_dmg)); + + return(READSTAT); +} + +int +rs_write_magic_items(FILE *savef, struct magic_item *i, int count) +{ + int n; + + rs_write_marker(savef, RSID_MAGICITEMS); + rs_write_int(savef, count); + + for(n=0;n<count;n++) + { +/* rs_write(savef,i[n].mi_name,sizeof(i[n].mi_name)); */ + rs_write_int(savef,i[n].mi_prob); +/* rs_write_int(savef,i[n].mi_worth); */ +/* rs_write_int(savef,i[n].mi_curse); */ +/* rs_write_int(savef,i[n].mi_bless); */ + } + + return(WRITESTAT); +} + +int +rs_read_magic_items(int inf, struct magic_item *mi, int count) +{ + int n; + int value; + + rs_read_marker(inf, RSID_MAGICITEMS); + + rs_read_int(inf, &value); + + if (value != count) + format_error = 1; + else + { + for(n = 0; n < value; n++) + { +/* rs_read(inf,mi[n].mi_name,sizeof(mi[n].mi_name)); */ + rs_read_int(inf,&mi[n].mi_prob); +/* rs_read_int(inf,&mi[n].mi_worth); */ +/* rs_read_int(inf,&mi[n].mi_curse); */ +/* rs_read_int(inf,&mi[n].mi_bless); */ + } + } + + return(READSTAT); +} + +int +rs_write_scrolls(FILE *savef) +{ + int i; + + if (write_error) + return(WRITESTAT); + + for(i = 0; i < MAXSCROLLS; i++) + { + rs_write_string(savef, s_names[i]); + rs_write_boolean(savef,s_know[i]); + rs_write_string(savef,s_guess[i]); + } + + return(WRITESTAT); +} + +int +rs_read_scrolls(int inf) +{ + int i; + + if (read_error || format_error) + return(READSTAT); + + for(i = 0; i < MAXSCROLLS; i++) + { + rs_read_new_string(inf,&s_names[i]); + rs_read_boolean(inf,&s_know[i]); + rs_read_new_string(inf,&s_guess[i]); + } + + return(READSTAT); +} + +int +rs_write_potions(FILE *savef) +{ + int i; + + if (write_error) + return(WRITESTAT); + + for(i = 0; i < MAXPOTIONS; i++) + { + rs_write_string_index(savef,rainbow,cNCOLORS,p_colors[i]); + rs_write_boolean(savef,p_know[i]); + rs_write_string(savef,p_guess[i]); + } + + return(WRITESTAT); +} + +int +rs_read_potions(int inf) +{ + int i; + + if (read_error || format_error) + return(READSTAT); + + for(i = 0; i < MAXPOTIONS; i++) + { + rs_read_string_index(inf,rainbow,cNCOLORS,&p_colors[i]); + rs_read_boolean(inf,&p_know[i]); + rs_read_new_string(inf,&p_guess[i]); + } + + return(READSTAT); +} + +int +rs_write_rings(FILE *savef) +{ + int i; + + if (write_error) + return(WRITESTAT); + + for(i = 0; i < MAXRINGS; i++) + { + rs_write_string_index(savef,stones,cNSTONES,r_stones[i]); + rs_write_boolean(savef,r_know[i]); + rs_write_string(savef,r_guess[i]); + } + + return(WRITESTAT); +} + +int +rs_read_rings(int inf) +{ + int i; + + if (read_error || format_error) + return(READSTAT); + + for(i = 0; i < MAXRINGS; i++) + { + rs_read_string_index(inf,stones,cNSTONES,&r_stones[i]); + rs_read_boolean(inf,&r_know[i]); + rs_read_new_string(inf,&r_guess[i]); + } + + return(READSTAT); +} + +int +rs_write_misc(FILE *savef) +{ + int i; + + if (read_error || format_error) + return(READSTAT); + + for(i = 0; i < MAXMM; i++) + { + rs_write_boolean(savef,m_know[i]); + rs_write_string(savef,m_guess[i]); + } + + return(READSTAT); +} + +int +rs_read_misc(int inf) +{ + int i; + + if (write_error) + return(WRITESTAT); + + for(i = 0; i < MAXMM; i++) + { + rs_read_boolean(inf,&m_know[i]); + rs_read_new_string(inf,&m_guess[i]); + } + + return(WRITESTAT); +} + +int +rs_write_sticks(FILE *savef) +{ + int i; + + if (write_error) + return(WRITESTAT); + + rs_write_marker(savef, RSID_STICKS); + + for (i = 0; i < MAXSTICKS; i++) + { + if (strcmp(ws_type[i],"staff") == 0) + { + rs_write_int(savef,0); + rs_write_string_index(savef,wood,cNWOOD,ws_made[i]); + } + else + { + rs_write_int(savef,1); + rs_write_string_index(savef,metal,cNMETAL,ws_made[i]); + } + + rs_write_boolean(savef, ws_know[i]); + rs_write_string(savef, ws_guess[i]); + } + + return(WRITESTAT); +} + +int +rs_read_sticks(int inf) +{ + int i = 0, j = 0, list = 0; + + if (read_error || format_error) + return(READSTAT); + + rs_read_marker(inf, RSID_STICKS); + + for(i = 0; i < MAXSTICKS; i++) + { + rs_read_int(inf,&list); + ws_made[i] = NULL; + + if (list == 0) + { + rs_read_string_index(inf,wood,cNWOOD,&ws_made[i]); + ws_type[i] = "staff"; + } + else + { + rs_read_string_index(inf,metal,cNMETAL,&ws_made[i]); + ws_type[i] = "wand"; + } + rs_read_boolean(inf, &ws_know[i]); + rs_read_new_string(inf, &ws_guess[i]); + } + + return(READSTAT); +} + +int +rs_write_daemons(FILE *savef, struct delayed_action *d_list, int count) +{ + int i = 0; + int func = 0; + + if (write_error) + return(WRITESTAT); + + rs_write_marker(savef, RSID_DAEMONS); + rs_write_int(savef, count); + + for(i = 0; i < count; i++) + { + if (d_list[i].d_func == rollwand) + func = 1; + else if (d_list[i].d_func == doctor) + func = 2; + else if (d_list[i].d_func == stomach) + func = 3; + else if (d_list[i].d_func == trap_look) + func = 4; + else if (d_list[i].d_func == eat_gold) + func = 5; + else if (d_list[i].d_func == ring_search) + func = 6; + else if (d_list[i].d_func == ring_teleport) + func = 7; + else if (d_list[i].d_func == fumble) + func = 8; + else if (d_list[i].d_func == strangle) + func = 9; + else if (d_list[i].d_func == unconfuse) + func = 10; + else if (d_list[i].d_func == swander) + func = 11; + else if (d_list[i].d_func == spell_recovery) + func = 12; + else if (d_list[i].d_func == chant_recovery) + func = 13; + else if (d_list[i].d_func == prayer_recovery) + func = 14; + else if (d_list[i].d_func == cure_disease) + func = 15; + else if (d_list[i].d_func == unstink) + func = 16; + else if (d_list[i].d_func == (int (*)()) res_strength) + func = 17; + else if (d_list[i].d_func == undance) + func = 18; + else if (d_list[i].d_func == suffocate) + func = 19; + else if (d_list[i].d_func == wghtchk) + func = 20; + else if (d_list[i].d_func == dust_appear) + func = 21; + else if (d_list[i].d_func == unchoke) + func = 22; + else if (d_list[i].d_func == sight) + func = 23; + else if (d_list[i].d_func == changeclass) + func = 24; + else if (d_list[i].d_func == cloak_charge) + func = 25; + else if (d_list[i].d_func == quill_charge) + func = 26; + else if (d_list[i].d_func == nohaste) + func = 27; + else if (d_list[i].d_func == noslow) + func = 28; + else if (d_list[i].d_func == unclrhead) + func = 29; + else if (d_list[i].d_func == unsee) + func = 30; + else if (d_list[i].d_func == unphase) + func = 31; + else if (d_list[i].d_func == land) + func = 32; + else if (d_list[i].d_func == appear) + func = 33; + else if (d_list[i].d_func == unskill) + func = 34; + else if (d_list[i].d_func == nofire) + func = 35; + else if (d_list[i].d_func == nocold) + func = 36; + else if (d_list[i].d_func == nobolt) + func = 37; + else if (d_list[i].d_func == NULL) + func = 0; + else + func = -1; + + rs_write_int(savef, d_list[i].d_type); + rs_write_int(savef, func); + + if (d_list[i].d_func == doctor) + rs_write_int(savef, 1); + else if (d_list[i].d_func == eat_gold) + { + int index; + index = find_list_ptr(player.t_pack, d_list[i].d_.varg); + rs_write_int(savef,index); + } + else if (d_list[i].d_func == changeclass) + { + rs_write_int(savef, d_list[i].d_.arg); + } + else if (d_list[i].d_func == cloak_charge) + { + int index; + index = find_list_ptr(player.t_pack, d_list[i].d_.varg); + rs_write_int(savef,index); + } + else + rs_write_int(savef, d_list[i].d_.arg); + + rs_write_int(savef, d_list[i].d_time); + } + + return(WRITESTAT); +} + +int +rs_read_daemons(int inf, struct delayed_action *d_list, int count) +{ + int i = 0; + int func = 0; + int value = 0; + int dummy = 0; + + if (read_error || format_error) + return(READSTAT); + + rs_read_marker(inf, RSID_DAEMONS); + rs_read_int(inf, &value); + + if (value > count) + format_error = TRUE; + + for(i=0; i < count; i++) + { + func = 0; + rs_read_int(inf, &d_list[i].d_type); + rs_read_int(inf, &func); + + switch(func) + { + case 1: d_list[i].d_func = rollwand; + break; + case 2: d_list[i].d_func = doctor; + break; + case 3: d_list[i].d_func = stomach; + break; + case 4: d_list[i].d_func = trap_look; + break; + case 5: d_list[i].d_func = eat_gold; + break; + case 6: d_list[i].d_func = ring_search; + break; + case 7: d_list[i].d_func = ring_teleport; + break; + case 8: d_list[i].d_func = fumble; + break; + case 9: d_list[i].d_func = strangle; + break; + case 10: d_list[i].d_func = unconfuse; + break; + case 11: d_list[i].d_func = swander; + break; + case 12: d_list[i].d_func = spell_recovery; + break; + case 13: d_list[i].d_func = chant_recovery; + break; + case 14: d_list[i].d_func = prayer_recovery; + break; + case 15: d_list[i].d_func = cure_disease; + break; + case 16: d_list[i].d_func = unstink; + break; + case 17: d_list[i].d_func = (int (*)()) res_strength; + break; + case 18: d_list[i].d_func = undance; + break; + case 19: d_list[i].d_func = suffocate; + break; + case 20: d_list[i].d_func = wghtchk; + break; + case 21: d_list[i].d_func = dust_appear; + break; + case 22: d_list[i].d_func = unchoke; + break; + case 23: d_list[i].d_func = sight; + break; + case 24: d_list[i].d_func = changeclass; + break; + case 25: d_list[i].d_func = cloak_charge; + break; + case 26: d_list[i].d_func = quill_charge; + break; + case 27: d_list[i].d_func = nohaste; + break; + case 28: d_list[i].d_func = noslow; + break; + case 29: d_list[i].d_func = unclrhead; + break; + case 30: d_list[i].d_func = unsee; + break; + case 31: d_list[i].d_func = unphase; + break; + case 32: d_list[i].d_func = land; + break; + case 33: d_list[i].d_func = appear; + break; + case 34: d_list[i].d_func = unskill; + break; + case 35: d_list[i].d_func = nofire; + break; + case 36: d_list[i].d_func = nocold; + break; + case 37: d_list[i].d_func = nobolt; + break; + case 0: + case -1: + default: d_list[i].d_func = NULL; + break; + } + + if (d_list[i].d_func == doctor) + { + rs_read_int(inf, &dummy); + d_list[i].d_.varg = &player; + } + else if (d_list[i].d_func == eat_gold) + { + rs_read_int(inf, &dummy); + d_list[i].d_.varg = get_list_item(player.t_pack, dummy); + if (d_list[i].d_.varg == NULL) + d_list[i].d_type = 0; + } + else if (d_list[i].d_func == changeclass) + { + rs_read_int(inf, &d_list[i].d_.arg); + } + else if (d_list[i].d_func == cloak_charge) + { + rs_read_int(inf, &dummy); + d_list[i].d_.varg = get_list_item(player.t_pack,dummy); + + if (d_list[i].d_.varg == NULL) + d_list[i].d_type = 0; + } + else + rs_read_int(inf, &d_list[i].d_.arg); + + rs_read_int(inf, &d_list[i].d_time); + + if (d_list[i].d_func == NULL) + { + d_list[i].d_time = 0; + d_list[i].d_.varg = NULL; + d_list[i].d_type = 0; + } + + } + + return(READSTAT); +} + +int +rs_write_room(FILE *savef, struct room *r) +{ + struct linked_list *l; + int i; + + if (write_error) + return(WRITESTAT); + + rs_write_coord(savef, r->r_pos); + rs_write_coord(savef, r->r_max); + rs_write_long(savef, r->r_flags); + + l = r->r_fires; + i = list_size(l); + + rs_write_int(savef, i); + + if (i >0) + while (l != NULL) + { + i = find_list_ptr(mlist, l->l_data); + rs_write_int(savef,i); + l = l->l_next; + } + + rs_write_coord_list(savef, r->r_exit); + + return(WRITESTAT); +} + +int +rs_read_room(int inf, struct room *r) +{ + int value = 0, n = 0, i = 0, index = 0, id = 0; + struct linked_list *fires=NULL, *item = NULL; + + if (read_error || format_error) + return(READSTAT); + + rs_read_coord(inf,&r->r_pos); + rs_read_coord(inf,&r->r_max); + rs_read_long(inf,&r->r_flags); + + rs_read_int(inf, &i); + fires = NULL; + + while (i>0) + { + rs_read_int(inf,&index); + + if (index >= 0) + { + void *data; + data = get_list_item(mlist,index); + item = creat_item(); + item->l_data = data; + if (fires == NULL) + fires = item; + else + attach(fires,item); + } + i--; + } + + r->r_fires=fires; + + rs_read_coord_list(inf, &r->r_exit); + + return(READSTAT); +} + +int +rs_write_rooms(FILE *savef, struct room r[], int count) +{ + int n = 0; + + if (write_error) + return(WRITESTAT); + + rs_write_int(savef, count); + + for(n = 0; n < count; n++) + rs_write_room(savef, &r[n]); + + return(WRITESTAT); +} + +int +rs_read_rooms(int inf, struct room *r, int count) +{ + int value = 0, n = 0; + + if (read_error || format_error) + return(READSTAT); + + rs_read_int(inf,&value); + + if (value > count) + format_error = TRUE; + + for(n = 0; n < value; n++) + rs_read_room(inf,&r[n]); + + return(READSTAT); +} + +int +rs_write_room_reference(FILE *savef, struct room *rp) +{ + int i, room = -1; + + if (write_error) + return(WRITESTAT); + + for (i = 0; i < MAXROOMS; i++) + if (&rooms[i] == rp) + room = i; + + rs_write_int(savef, room); + + return(WRITESTAT); +} + +int +rs_read_room_reference(int inf, struct room **rp) +{ + int i; + + if (read_error || format_error) + return(READSTAT); + + rs_read_int(inf, &i); + + *rp = &rooms[i]; + + return(READSTAT); +} + +int +rs_write_door_reference(FILE *savef, coord *exit) +{ + int i, idx; + + for (i = 0; i < MAXROOMS; i++) + { + idx = find_list_ptr(rooms[i].r_exit, exit); + + if (idx != -1) + break; + } + + if (i >= MAXROOMS) + { + rs_write_int(savef,-1); + rs_write_int(savef,-1); + if (exit != NULL) + abort(); + } + else + { + rs_write_int(savef,i); + rs_write_int(savef,idx); + } + + return(WRITESTAT); +} + +int +rs_read_door_reference(int inf, coord **exit) +{ + int i, idx; + + rs_read_int(inf, &i); + rs_read_int(inf, &idx); + + if ( (i == -1) || (idx == -1) ) + *exit = NULL; + else + *exit = get_list_item(rooms[i].r_exit, idx); + + return(READSTAT); +} + +int +rs_write_traps(FILE *savef, struct trap *trap,int count) +{ + int n; + + rs_write_int(savef, RSID_TRAP); + rs_write_int(savef, count); + + for(n=0; n<count; n++) + { + rs_write_char(savef, trap[n].tr_type); + rs_write_char(savef, trap[n].tr_show); + rs_write_coord(savef, trap[n].tr_pos); + rs_write_long(savef, trap[n].tr_flags); + } +} + +int +rs_read_traps(int inf, struct trap *trap, int count) +{ + int id = 0, value = 0, n = 0; + + if (rs_read_int(inf,&id) != 0) + format_error = TRUE; + else if (rs_read_int(inf,&value) != 0) + { + if (value != count) + format_error = TRUE; + } + else + { + for(n=0;n<value;n++) + { + rs_read_char(inf,&trap[n].tr_type); + rs_read_char(inf,&trap[n].tr_show); + rs_read_coord(inf,&trap[n].tr_pos); + rs_read_long(inf,&trap[n].tr_flags); + } + } + + return(READSTAT); +} + +int +rs_write_monsters(FILE *savef, struct monster *m, int count) +{ + int n; + + if (write_error) + return(WRITESTAT); + + rs_write_marker(savef, RSID_MONSTERS); + rs_write_int(savef, count); + + for(n=0;n<count;n++) + { + rs_write_boolean(savef, m[n].m_normal); + rs_write_boolean(savef, m[n].m_wander); + rs_write_short(savef, m[n].m_numsum); + } + + return(WRITESTAT); +} + +int +rs_read_monsters(int inf, struct monster *m, int count) +{ + int value = 0, n = 0; + + if (read_error || format_error) + return(READSTAT); + + rs_read_marker(inf, RSID_MONSTERS); + + rs_read_int(inf, &value); + + if (value != count) + format_error = TRUE; + + for(n = 0; n < count; n++) + { + rs_read_boolean(inf, &m[n].m_normal); + rs_read_boolean(inf, &m[n].m_wander); + rs_read_short(inf, &m[n].m_numsum); + } + + return(READSTAT); +} + +int +rs_write_object(FILE *savef, struct object *o) +{ + if (write_error) + return(WRITESTAT); + + rs_write_marker(savef, RSID_OBJECT); + rs_write_int(savef, o->o_type); + rs_write_coord(savef, o->o_pos); + rs_write_char(savef, o->o_launch); + rs_write(savef, o->o_damage, sizeof(o->o_damage)); + rs_write(savef, o->o_hurldmg, sizeof(o->o_hurldmg)); + rs_write_object_list(savef, o->contents); + rs_write_int(savef, o->o_count); + rs_write_int(savef, o->o_which); + rs_write_int(savef, o->o_hplus); + rs_write_int(savef, o->o_dplus); + rs_write_int(savef, o->o_ac); + rs_write_long(savef, o->o_flags); + rs_write_int(savef, o->o_group); + rs_write_int(savef, o->o_weight); + rs_write(savef, o->o_mark, MARKLEN); + + + return(WRITESTAT); +} + +int +rs_read_object(int inf, struct object *o) +{ + if (read_error || format_error) + return(READSTAT); + + rs_read_marker(inf, RSID_OBJECT); + rs_read_int(inf, &o->o_type); + rs_read_coord(inf, &o->o_pos); + rs_read_char(inf, &o->o_launch); + rs_read(inf, o->o_damage, sizeof(o->o_damage)); + rs_read(inf, o->o_hurldmg, sizeof(o->o_hurldmg)); + rs_read_object_list(inf,&o->contents); + rs_read_int(inf, &o->o_count); + rs_read_int(inf, &o->o_which); + rs_read_int(inf, &o->o_hplus); + rs_read_int(inf, &o->o_dplus); + rs_read_int(inf, &o->o_ac); + rs_read_long(inf,&o->o_flags); + rs_read_int(inf, &o->o_group); + rs_read_int(inf, &o->o_weight); + rs_read(inf, o->o_mark, MARKLEN); + + return(READSTAT); +} + +int +rs_write_object_list(FILE *savef, struct linked_list *l) +{ + if (write_error) + return(WRITESTAT); + + rs_write_marker(savef, RSID_OBJECTLIST); + rs_write_int(savef, list_size(l)); + + for( ;l != NULL; l = l->l_next) + rs_write_object(savef, OBJPTR(l)); + + return(WRITESTAT); +} + +int +rs_read_object_list(int inf, struct linked_list **list) +{ + int i, cnt; + struct linked_list *l = NULL, *previous = NULL, *head = NULL; + + if (read_error || format_error) + return(READSTAT); + + rs_read_marker(inf, RSID_OBJECTLIST); + rs_read_int(inf, &cnt); + + for (i = 0; i < cnt; i++) + { + l = new_item(sizeof(struct object)); + + l->l_prev = previous; + + if (previous != NULL) + previous->l_next = l; + + rs_read_object(inf,OBJPTR(l)); + + if (previous == NULL) + head = l; + + previous = l; + } + + if (l != NULL) + l->l_next = NULL; + + *list = head; + + return(READSTAT); +} + +int +rs_write_object_reference(FILE *savef, struct linked_list *list, struct object *item) +{ + int i; + + if (write_error) + return(WRITESTAT); + + i = find_list_ptr(list, item); + + rs_write_int(savef, i); + + return(WRITESTAT); +} + +int +rs_read_object_reference(int inf, struct linked_list *list, struct object **item) +{ + int i; + + if (read_error || format_error) + return(READSTAT); + + rs_read_int(inf, &i); + + *item = get_list_item(list,i); + + return(READSTAT); +} + +int +find_thing_coord(struct linked_list *monlist, coord *c) +{ + struct linked_list *mitem; + struct thing *tp; + int i = 0; + + for(mitem = monlist; mitem != NULL; mitem = mitem->l_next) + { + tp = THINGPTR(mitem); + + if (c == &tp->t_pos) + return(i); + + i++; + } + + return(-1); +} + +int +find_object_coord(struct linked_list *objlist, coord *c) +{ + struct linked_list *oitem; + struct object *obj; + int i = 0; + + for(oitem = objlist; oitem != NULL; oitem = oitem->l_next) + { + obj = OBJPTR(oitem); + + if (c == &obj->o_pos) + return(i); + + i++; + } + + return(-1); +} + +int +rs_write_thing(FILE *savef, struct thing *t) +{ + int i = -1; + + if (write_error) + return(WRITESTAT); + + rs_write_marker(savef, RSID_THING); + + if (t == NULL) + { + rs_write_int(savef, 0); + return(WRITESTAT); + } + + rs_write_int(savef, 1); + rs_write_boolean(savef,t->t_wasshot); + rs_write_char(savef, t->t_type); + rs_write_char(savef, t->t_disguise); + rs_write_char(savef, t->t_oldch); + rs_write_short(savef, t->t_ctype); + rs_write_short(savef, t->t_index); + rs_write_short(savef, t->t_no_move); + rs_write_short(savef, t->t_quiet); + rs_write_short(savef, t->t_movement); + rs_write_short(savef, t->t_action); + rs_write_short(savef, t->t_artifact); + rs_write_short(savef, t->t_wand); + rs_write_short(savef, t->t_summon); + rs_write_short(savef, t->t_cast); + rs_write_short(savef, t->t_breathe); + + rs_write_string(savef,t->t_name); + rs_write_door_reference(savef, t->t_doorgoal); + + if (t->t_dest == &hero) + { + rs_write_int(savef,0); + rs_write_int(savef,1); + } + else if (t->t_dest != NULL) + { + i = find_thing_coord(mlist, t->t_dest); + + if (i >= 0) + { + rs_write_int(savef,1); + rs_write_int(savef,i); + } + else + { + i = find_object_coord(lvl_obj, t->t_dest); + + if (i >= 0) + { + rs_write_int(savef,2); + rs_write_int(savef,i); + } + else + { + rs_write_int(savef,0); + rs_write_int(savef,1); /* chase the hero anyway */ + } + } + } + else + { + rs_write_int(savef,0); + rs_write_int(savef,0); + } + + rs_write_coord(savef, t->t_pos); + rs_write_coord(savef, t->t_oldpos); + rs_write_coord(savef, t->t_newpos); + rs_write_ulongs(savef, t->t_flags, 16); + rs_write_object_list(savef, t->t_pack); + i = -1; + if (t->t_using != NULL) + i = find_list_ptr(t->t_pack, t->t_using->l_data); + rs_write_int(savef, i); + rs_write_int(savef, t->t_selection); + rs_write_stats(savef, &t->t_stats); + rs_write_stats(savef, &t->maxstats); + + return(WRITESTAT); +} + +int +rs_read_thing(int inf, struct thing *t) +{ + int listid = 0, index = -1; + + if (read_error || format_error) + return(READSTAT); + + rs_read_marker(inf, RSID_THING); + + rs_read_int(inf, &index); + + if (index == 0) + return(READSTAT); + + rs_read_boolean(inf, &t->t_wasshot); + rs_read_char(inf, &t->t_type); + rs_read_char(inf, &t->t_disguise); + rs_read_char(inf, &t->t_oldch); + rs_read_short(inf, &t->t_ctype); + rs_read_short(inf, &t->t_index); + rs_read_short(inf, &t->t_no_move); + rs_read_short(inf, &t->t_quiet); + rs_read_short(inf, &t->t_movement); + rs_read_short(inf, &t->t_action); + rs_read_short(inf, &t->t_artifact); + rs_read_short(inf, &t->t_wand); + rs_read_short(inf, &t->t_summon); + rs_read_short(inf, &t->t_cast); + rs_read_short(inf, &t->t_breathe); + rs_read_new_string(inf,&t->t_name); + rs_read_door_reference(inf,&t->t_doorgoal); + + rs_read_int(inf,&listid); + rs_read_int(inf,&index); + t->t_reserved = -1; + if (listid == 0) + { + if (index == 1) + t->t_dest = &hero; + else + t->t_dest = NULL; + } + else if (listid == 1) + { + t->t_dest = NULL; + t->t_reserved = index; + } + else if (listid == 2) + { + struct object *obj; + obj = get_list_item(lvl_obj,index); + if (obj != NULL) + { + t->t_dest = &obj->o_pos; + } + } + else + t->t_dest = NULL; + + rs_read_coord(inf,&t->t_pos); + rs_read_coord(inf,&t->t_oldpos); + rs_read_coord(inf,&t->t_newpos); + rs_read_ulongs(inf,t->t_flags,16); + rs_read_object_list(inf,&t->t_pack); + rs_read_int(inf,&index); + t->t_using = get_list_item(t->t_pack, index); + rs_read_int(inf, &t->t_selection); + rs_read_stats(inf,&t->t_stats); + rs_read_stats(inf,&t->maxstats); + + return(READSTAT); +} + +int +rs_fix_thing(struct thing *t) +{ + struct thing *tp; + + if (t->t_reserved < 0) + return; + + tp = get_list_item(mlist,t->t_reserved); + + if (tp != NULL) + { + t->t_dest = &tp->t_pos; + } +} + +int +rs_write_thing_list(FILE *savef, struct linked_list *l) +{ + int cnt = 0; + + if (write_error) + return(WRITESTAT); + + rs_write_marker(savef, RSID_MONSTERLIST); + + cnt = list_size(l); + + rs_write_int(savef, cnt); + + if (cnt < 1) + return(WRITESTAT); + + while (l != NULL) { + rs_write_thing(savef, (struct thing *)l->l_data); + l = l->l_next; + } + + return(WRITESTAT); +} + +int +rs_read_thing_list(int inf, struct linked_list **list) +{ + int i, cnt; + struct linked_list *l = NULL, *previous = NULL, *head = NULL; + + if (read_error || format_error) + return(READSTAT); + + rs_read_marker(inf, RSID_MONSTERLIST); + + rs_read_int(inf, &cnt); + + for (i = 0; i < cnt; i++) + { + l = new_item(sizeof(struct thing)); + + l->l_prev = previous; + + if (previous != NULL) + previous->l_next = l; + + rs_read_thing(inf,THINGPTR(l)); + + if (previous == NULL) + head = l; + + previous = l; + } + + if (l != NULL) + l->l_next = NULL; + + *list = head; + + return(READSTAT); +} + +int +rs_fix_thing_list(struct linked_list *list) +{ + struct linked_list *item; + + for(item = list; item != NULL; item = item->l_next) + rs_fix_thing(THINGPTR(item)); +} + +int +rs_write_thing_reference(FILE *savef, struct linked_list *list, struct thing *item) +{ + int i; + + if (write_error) + return(WRITESTAT); + + if (item == NULL) + rs_write_int(savef,-1); + else + { + i = find_list_ptr(list, item); + + rs_write_int(savef, i); + } + + return(WRITESTAT); +} + +int +rs_read_thing_reference(int inf, struct linked_list *list, struct thing **item) +{ + int i; + + if (read_error || format_error) + return(READSTAT); + + rs_read_int(inf, &i); + + if (i == -1) + *item = NULL; + else + *item = get_list_item(list,i); + + return(READSTAT); +} + +int +rs_write_thing_references(FILE *savef, struct linked_list *list, struct thing *items[], int count) +{ + int i; + + if (write_error) + return(WRITESTAT); + + for(i = 0; i < count; i++) + rs_write_thing_reference(savef,list,items[i]); + + return(WRITESTAT); +} + +int +rs_read_thing_references(int inf, struct linked_list *list, struct thing *items[], int count) +{ + int i; + + if (read_error || format_error) + return(READSTAT); + + for(i = 0; i < count; i++) + rs_read_thing_reference(inf,list,&items[i]); + + return(WRITESTAT); +} + +int +rs_save_file(FILE *savef) +{ + int i; + + if (write_error) + return(WRITESTAT); + + rs_write_object_list(savef, lvl_obj); + rs_write_thing(savef, &player); + rs_write_thing_list(savef, mlist); + rs_write_thing_list(savef, tlist); + rs_write_thing_list(savef, monst_dead); + + rs_write_traps(savef, traps, MAXTRAPS); + rs_write_rooms(savef, rooms, MAXROOMS); + rs_write_room_reference(savef,oldrp); + + rs_write_object_reference(savef, player.t_pack, cur_armor); + + for (i = 0; i < NUM_FINGERS; i++) + rs_write_object_reference(savef, player.t_pack, cur_ring[i]); + + for (i = 0; i < NUM_MM; i++) + rs_write_object_reference(savef, player.t_pack, cur_misc[i]); + + rs_write_ints(savef, cur_relic, MAXRELIC); + + rs_write_object_reference(savef, player.t_pack, cur_weapon); + + rs_write_int(savef,char_type); + rs_write_int(savef,foodlev); + rs_write_int(savef,ntraps); + rs_write_int(savef,trader); + rs_write_int(savef,curprice); + rs_write_int(savef,seed); + rs_write_int(savef,dnum); + rs_write_int(savef,max_level); + rs_write_int(savef,cur_max); + rs_write_int(savef,mpos); + rs_write_int(savef,level); + rs_write_int(savef,purse); + rs_write_int(savef,inpack); + rs_write_int(savef,total); + rs_write_int(savef,no_food); + rs_write_int(savef,foods_this_level); + rs_write_int(savef,count); + rs_write_int(savef,food_left); + rs_write_int(savef,group); + rs_write_int(savef,hungry_state); + rs_write_int(savef,infest_dam); + rs_write_int(savef,lost_str); + rs_write_int(savef,lastscore); + rs_write_int(savef,hold_count); + rs_write_int(savef,trap_tries); + rs_write_int(savef,chant_time); + rs_write_int(savef,pray_time); + rs_write_int(savef,spell_power); + rs_write_int(savef,turns); + rs_write_int(savef,quest_item); + rs_write_int(savef,cols); + rs_write_int(savef,lines); + rs_write_char(savef,nfloors); + rs_write(savef,curpurch,LINELEN); + rs_write_char(savef,PLAYER); + rs_write_char(savef,take); + rs_write(savef,prbuf,LINELEN*2); + rs_write(savef,outbuf,BUFSIZ); + rs_write_char(savef,runch); + rs_write_scrolls(savef); + rs_write_potions(savef); + rs_write_rings(savef); + rs_write_sticks(savef); + rs_write_misc(savef); + rs_write(savef,whoami,LINELEN); + rs_write(savef,huh,LINELEN); + rs_write(savef,file_name,LINELEN); + rs_write(savef,score_file,LINELEN); + rs_write(savef,home,LINELEN); + rs_write_window(savef, cw); + rs_write_window(savef, hw); + rs_write_window(savef, mw); + rs_write_window(savef, msgw); + rs_write_window(savef, stdscr); + rs_write_boolean(savef, pool_teleport); + rs_write_boolean(savef, inwhgt); + rs_write_boolean(savef, after); + rs_write_boolean(savef, waswizard); + rs_write_boolean(savef, playing); + rs_write_boolean(savef, running); + rs_write_boolean(savef, wizard); + rs_write_boolean(savef, notify); + rs_write_boolean(savef, fight_flush); + rs_write_boolean(savef, terse); + rs_write_boolean(savef, auto_pickup); + rs_write_boolean(savef, menu_overlay); + rs_write_boolean(savef, door_stop); + rs_write_boolean(savef, jump); + rs_write_boolean(savef, slow_invent); + rs_write_boolean(savef, firstmove); + rs_write_boolean(savef, askme); + rs_write_boolean(savef, in_shell); + rs_write_boolean(savef, daytime); + rs_write_levtype(savef, levtype); + rs_write_magic_items(savef, things, MAXTHINGS); + rs_write_magic_items(savef, s_magic, MAXSCROLLS); + rs_write_magic_items(savef, p_magic, MAXPOTIONS); + rs_write_magic_items(savef, r_magic, MAXRINGS); + rs_write_magic_items(savef, ws_magic, MAXSTICKS); + rs_write_magic_items(savef, m_magic, MAXMM); + rs_write_magic_items(savef, rel_magic, MAXRELIC); + rs_write_magic_items(savef, foods, MAXFOODS); + + rs_write_monsters(savef, monsters, NUMMONST+1); + + rs_write_daemons(savef, d_list, MAXDAEMONS); + rs_write_daemons(savef, f_list, MAXFUSES); + rs_write_int(savef, demoncnt); + rs_write_int(savef, fusecnt); + + rs_write_int(savef, between); + + rs_write_int(savef, chance); + + return(WRITESTAT); +} + +int +rs_restore_file(int inf) +{ + int i; + + if (read_error || format_error) + return(READSTAT); + + rs_read_object_list(inf, &lvl_obj); + rs_read_thing(inf, &player); + rs_read_thing_list(inf, &mlist); + rs_read_thing_list(inf, &tlist); + rs_read_thing_list(inf, &monst_dead); + + rs_fix_thing(&player); + rs_fix_thing_list(mlist); + rs_fix_thing_list(tlist); + rs_fix_thing_list(monst_dead); + + rs_read_traps(inf, traps, MAXTRAPS); + rs_read_rooms(inf, rooms, MAXROOMS); + rs_read_room_reference(inf,&oldrp); + + rs_read_object_reference(inf, player.t_pack, &cur_armor); + + for(i = 0; i < NUM_FINGERS; i++) + rs_read_object_reference(inf, player.t_pack, &cur_ring[i]); + + for(i = 0; i < NUM_MM; i++) + rs_read_object_reference(inf, player.t_pack, &cur_misc[i]); + + rs_read_ints(inf, cur_relic, MAXRELIC); + + rs_read_object_reference(inf, player.t_pack, &cur_weapon); + + rs_read_int(inf,&char_type); + rs_read_int(inf,&foodlev); + rs_read_int(inf,&ntraps); + rs_read_int(inf,&trader); + rs_read_int(inf,&curprice); + rs_read_int(inf,&seed); + rs_read_int(inf,&dnum); + rs_read_int(inf,&max_level); + rs_read_int(inf,&cur_max); + rs_read_int(inf,&mpos); + rs_read_int(inf,&level); + rs_read_int(inf,&purse); + rs_read_int(inf,&inpack); + rs_read_int(inf,&total); + rs_read_int(inf,&no_food); + rs_read_int(inf,&foods_this_level); + rs_read_int(inf,&count); + rs_read_int(inf,&food_left); + rs_read_int(inf,&group); + rs_read_int(inf,&hungry_state); + rs_read_int(inf,&infest_dam); + rs_read_int(inf,&lost_str); + rs_read_int(inf,&lastscore); + rs_read_int(inf,&hold_count); + rs_read_int(inf,&trap_tries); + rs_read_int(inf,&chant_time); + rs_read_int(inf,&pray_time); + rs_read_int(inf,&spell_power); + rs_read_int(inf,&turns); + rs_read_int(inf,&quest_item); + rs_read_int(inf,&cols); + rs_read_int(inf,&lines); + rs_read_char(inf,&nfloors); + rs_read(inf,curpurch,LINELEN); + rs_read_char(inf,&PLAYER); + rs_read_char(inf,&take); + rs_read(inf,prbuf,LINELEN*2); + rs_read(inf,outbuf,BUFSIZ); + rs_read_char(inf,&runch); + rs_read_scrolls(inf); + rs_read_potions(inf); + rs_read_rings(inf); + rs_read_sticks(inf); + rs_read_misc(inf); + rs_read(inf,whoami,LINELEN); + rs_read(inf,huh,LINELEN); + rs_read(inf,file_name,LINELEN); + rs_read(inf,score_file,LINELEN); + rs_read(inf,home,LINELEN); + rs_read_window(inf, cw); + rs_read_window(inf, hw); + rs_read_window(inf, mw); + rs_read_window(inf, msgw); + rs_read_window(inf, stdscr); + rs_read_boolean(inf, &pool_teleport); + rs_read_boolean(inf, &inwhgt); + rs_read_boolean(inf, &after); + rs_read_boolean(inf, &waswizard); + rs_read_boolean(inf, &playing); + rs_read_boolean(inf, &running); + rs_read_boolean(inf, &wizard); + rs_read_boolean(inf, ¬ify); + rs_read_boolean(inf, &fight_flush); + rs_read_boolean(inf, &terse); + rs_read_boolean(inf, &auto_pickup); + rs_read_boolean(inf, &menu_overlay); + rs_read_boolean(inf, &door_stop); + rs_read_boolean(inf, &jump); + rs_read_boolean(inf, &slow_invent); + rs_read_boolean(inf, &firstmove); + rs_read_boolean(inf, &askme); + rs_read_boolean(inf, &in_shell); + rs_read_boolean(inf, &daytime); + rs_read_levtype(inf, &levtype); + rs_read_magic_items(inf, things, MAXTHINGS); + rs_read_magic_items(inf, s_magic, MAXSCROLLS); + rs_read_magic_items(inf, p_magic, MAXPOTIONS); + rs_read_magic_items(inf, r_magic, MAXRINGS); + rs_read_magic_items(inf, ws_magic, MAXSTICKS); + rs_read_magic_items(inf, m_magic, MAXMM); + rs_read_magic_items(inf, rel_magic, MAXRELIC); + rs_read_magic_items(inf, foods, MAXFOODS); + rs_read_monsters(inf, monsters, NUMMONST + 1); + + rs_read_daemons(inf, d_list, MAXDAEMONS); + rs_read_daemons(inf, f_list, MAXFUSES); + rs_read_int(inf, &demoncnt); + rs_read_int(inf, &fusecnt); + + rs_read_int(inf, &between); + + rs_read_int(inf, &chance); + + return(READSTAT); +}