comparison urogue/state.c @ 256:c495a4f288c6

Import UltraRogue from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 31 Jan 2017 19:56:04 -0500
parents
children 2908dc47f9e2
comparison
equal deleted inserted replaced
253:d9badb9c0179 256:c495a4f288c6
1 /*
2 state.c - Portable Rogue Save State Code
3
4 Copyright (C) 1993, 1995 Nicholas J. Kisseberth
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 2. Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14 3. Neither the name(s) of the author(s) nor the names of other contributors
15 may be used to endorse or promote products derived from this software
16 without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
22 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 SUCH DAMAGE.
29 */
30
31 /*
32 Notes
33
34 Should move all game variables into one place
35 Should move save/restore code into save.c or some such
36 */
37
38 #include <assert.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include "rogue.h"
42
43 /*
44 Variables for global game state.
45
46 All variables that need to get saved when saving a game
47 are defined in this file. Long term goal is to move many
48 of these variables into a "struct level" data type of some
49 kind... perhaps not, maybe struct game...
50
51 Other global variables that don't need to get saved are
52 kept in main.c.
53
54 Other global variables that don't change during the course
55 of a game are kept in urogue.c, monsdata.c, data.c.
56 */
57
58 #define _X_ { 0, 0, 0, 0, 0 }
59
60 struct delayed_action
61 d_list[MAXDAEMONS] = /* daemon/fuse list */
62 {
63 _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_,
64 _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_,
65 _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_,
66 _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_,
67 _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_,
68 _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_,
69 };
70
71 #undef _X_
72
73 char *s_names[MAXSCROLLS]; /* Names of the scrolls */
74 char *p_colors[MAXPOTIONS]; /* Colors of the potions */
75 char *r_stones[MAXRINGS]; /* Stone settings of the rings */
76 char *ws_made[MAXSTICKS]; /* What sticks are made of */
77 char *ws_type[MAXSTICKS]; /* Is it a wand or a staff */
78
79 char *guess_items[MAXMAGICTYPES][MAXMAGICITEMS]; /* guess magic is */
80 int know_items[MAXMAGICTYPES][MAXMAGICITEMS]; /* flag knowlede of magic */
81 /* object data */
82
83 struct trap traps[2 * MAXTRAPS]; /* 2x for special effects */
84 struct room rooms[MAXROOMS]; /* One for each room -- A level */
85 struct room *oldrp = NULL; /* Roomin(&player.t_oldpos) */
86 struct thing player; /* The rogue */
87 struct linked_list *lvl_obj = NULL; /* Treasure on this level */
88 struct linked_list *fam_ptr = NULL; /* A ptr to the familiar */
89 struct linked_list *mlist = NULL; /* Monsters on this level */
90 struct thing *beast; /* The last beast that attacked */
91 struct object *cur_armor = NULL; /* what rogue wears */
92 struct object *cur_weapon = NULL; /* ... and wields */
93 struct object *cur_ring[10]; /* His rings */
94 struct linked_list *curr_mons = NULL; /* The mons. currently moving */
95 struct linked_list *next_mons = NULL; /* The mons. after curr_mons */
96
97 /* Misc. game state info */
98 char dummybuf1[50000];
99 char dummybuf2[50000];
100 char msgbuf[10][2*LINELEN]; /* message buffer history */
101 int msg_index = 0; /* index in msg history buffer for nxt msg */
102 int foodlev = 1; /* how fast he eats food */
103 int ntraps = 0; /* Number of traps on this level */
104 int dnum = 0; /* Dungeon number */
105 int max_level = 0; /* Deepest player has gone */
106 int lost_dext = 0; /* amount of lost dexterity */
107 int no_command = 0;
108 int level = 0;
109 int see_dist = 3;
110 int no_food = 0;
111 int count = 0;
112 int food_left = HUNGERTIME;
113 int group = 1;
114 int hungry_state = F_OK;
115 int infest_dam = 0;
116 int lost_str = 0;
117 int hold_count = 0;
118 int trap_tries = 0;
119 int has_artifact = 0;
120 int picked_artifact = 0;
121 int luck = 0;
122 int resurrect = 0;
123 int fam_type = 0; /* The type of familiar */
124 int mons_summoned = 0; /* Number of summoned monsters */
125 char PLAYER = VPLAYER; /* what the player looks like */
126 char take = 0; /* Thing the rogue is taking */
127 char runch = 0; /* Direction player is running */
128 int char_type = C_NOTSET; /* what type of character is player */
129 int inv_type = INV_CLEAR; /* Overwrite style of inventory */
130 int pool_teleport = FALSE; /* just teleported from a pool */
131 int inwhgt = FALSE; /* true if from wghtchk() */
132 int after = 0; /* True if we want after daemons */
133 int waswizard = 0; /* Was a wizard sometime */
134 int canwizard = 1; /* Will be permitted to do this */
135 int playing = TRUE;
136 int running = FALSE;
137 int fighting = FALSE;
138 int wizard = FALSE;
139 int wiz_verbose = TRUE;
140 int moving = FALSE;
141 coord delta; /* Change indicated to get_dir() */
142 LEVTYPE levtype; /* type of level i'm on */
143 long purse = 0;
144 unsigned long total = 0;
145
146 WINDOW *cw; /* Window that the player sees */
147 WINDOW *hw; /* Used for the help command */
148 WINDOW *mw; /* Used to store mosnters */
149
150 /* options.o */
151 /* game options */
152
153 int terse = FALSE;
154 int door_stop = FALSE;
155 int jump = TRUE;
156 int doorstop = TRUE;
157 int firstmove = FALSE;
158 int askme = FALSE;
159 char whoami[2 * LINELEN]; /* Name of player */
160 char fruit[2 * LINELEN]; /* Favorite fruit */
161 char file_name[2 * LINELEN]; /* Save file name */
162 char score_file[2 * LINELEN]; /* Score file name */
163
164 /****************************************************************************/
165 /* Portable Save State Code */
166 /* */
167 /* UltraRogue v1.04 */
168 /****************************************************************************/
169
170 #define URS_STATS 0xABCD0001
171 #define URS_THING 0xABCD0002
172 #define URS_OBJECT 0xABCD0003
173 #define URS_MAGIC 0xABCD0004
174 #define URS_KNOWS 0xABCD0005
175 #define URS_GUESSES 0xABCD0006
176 #define URS_STACKOBJECT 0xABCD0007
177 #define URS_BAGOBJECT 0xABCD0008
178 #define URS_MONSTERLIST 0xABCD0009
179 #define URS_MONSTERSTATS 0xABCD000A
180 #define URS_MONSTER 0xABCD000B
181 #define URS_TRAP 0xABCD000C
182 #define URS_WINDOW 0xABCD000D
183 #define URS_DAEMONS 0xABCD000E
184
185 void
186 ur_write(FILE *savef, void *ptr, size_t size)
187 {
188 if (size == 0)
189 return;
190
191 fwrite(ptr,size,1,savef);
192 }
193
194 void
195 ur_read(FILE *savef, void *ptr, size_t size)
196 {
197 if (size == 0)
198 return;
199
200 fread(ptr,size,1,savef);
201 }
202
203 void
204 ur_write_int(FILE *savef, int c)
205 {
206 ur_write(savef,&c,sizeof(int));
207 }
208
209 int
210 ur_read_int(FILE *savef)
211 {
212 int i;
213
214 ur_read(savef, &i, sizeof(int));
215
216 return(i);
217 }
218
219 void
220 ur_write_short(FILE *savef, short c)
221 {
222 ur_write(savef,&c,sizeof(short));
223 }
224
225 short
226 ur_read_short(FILE *savef)
227 {
228 short s;
229
230 ur_read(savef, &s, sizeof(short));
231
232 return(s);
233 }
234
235 void
236 ur_write_long(FILE *savef, long c)
237 {
238 ur_write(savef,&c,sizeof(long));
239 }
240
241 long
242 ur_read_long(FILE *savef)
243 {
244 long l;
245
246 ur_read(savef, &l, sizeof(long));
247
248 return(l);
249 }
250
251 void
252 ur_write_ulong(FILE *savef, unsigned long c)
253 {
254 ur_write(savef,&c,sizeof(unsigned long));
255 }
256
257 unsigned long
258 ur_read_ulong(FILE *savef)
259 {
260 long l;
261
262 ur_read(savef, &l, sizeof(unsigned long));
263
264 return(l);
265 }
266
267 void
268 ur_unread_long(FILE *savef)
269 {
270 fseek(savef, -(long)sizeof(long), SEEK_CUR);
271 }
272
273 void
274 ur_write_char(FILE *savef, char c)
275 {
276 ur_write(savef,&c,sizeof(char));
277 }
278
279 char
280 ur_read_char(FILE *savef)
281 {
282 char c;
283
284 ur_read(savef, &c, sizeof(char));
285
286 return(c);
287 }
288
289 void
290 ur_write_string(FILE *savef, char *s)
291 {
292 size_t len;
293
294 len = (s == NULL) ? 0L : strlen(s) + 1 ;
295
296 ur_write_long(savef, (long) len);
297 ur_write(savef,s,len);
298 }
299
300
301 char *
302 ur_read_string(FILE *savef)
303 {
304 size_t len;
305 char *buf;
306
307 len = ur_read_long(savef);
308
309 if (len == 0)
310 return(NULL);
311
312 buf = ur_alloc(len);
313
314 if (buf == NULL) /* Should flag a global error condition... */
315 return(NULL);
316
317 ur_read(savef,buf,len);
318
319 return(buf);
320 }
321
322 void
323 ur_write_coord(FILE *savef, coord c)
324 {
325 ur_write_int(savef, c.x);
326 ur_write_int(savef, c.y);
327 }
328
329 coord
330 ur_read_coord(FILE *savef)
331 {
332 coord c;
333
334 c.x = ur_read_int(savef);
335 c.y = ur_read_int(savef);
336
337 return(c);
338 }
339
340 void
341 ur_write_room(FILE *savef, struct room *r)
342 {
343 int i;
344
345 ur_write_coord(savef, r->r_pos);
346 ur_write_coord(savef, r->r_max);
347
348 for(i=0; i<MAXDOORS; i++)
349 ur_write_coord(savef, r->r_exit[i]);
350
351 ur_write_int(savef, r->r_flags);
352 ur_write_int(savef, r->r_nexits);
353 ur_write_int(savef, r->r_flags);
354 }
355
356 struct room *
357 ur_read_room(FILE *savef)
358 {
359 struct room *r;
360 int i;
361
362 r = ur_alloc( sizeof(struct room) );
363
364 r->r_pos = ur_read_coord(savef);
365 r->r_max = ur_read_coord(savef);
366
367 for(i=0; i<MAXDOORS; i++)
368 r->r_exit[i] = ur_read_coord(savef);
369
370 r->r_flags = ur_read_int(savef);
371 r->r_nexits = ur_read_int(savef);
372 r->r_flags = ur_read_short(savef);
373
374 return(r);
375 }
376
377 void
378 ur_write_object(FILE *savef, struct object *o)
379 {
380 int other;
381
382 ur_write_long(savef, URS_OBJECT);
383 ur_write_coord(savef, o->o_pos);
384 ur_write_string(savef, o->o_text);
385 ur_write_string(savef, o->o_damage);
386 ur_write_string(savef, o->o_hurldmg);
387 ur_write_long(savef, o->o_flags);
388 ur_write_long(savef, o->ar_flags);
389 ur_write_char(savef, o->o_type);
390 ur_write_int(savef, o->o_ident);
391 ur_write_int(savef, o->o_count);
392 ur_write_int(savef, o->o_which);
393 ur_write_int(savef, o->o_hplus);
394 ur_write_int(savef, o->o_dplus);
395 ur_write_int(savef, o->o_ac);
396 ur_write_int(savef, o->o_group);
397 ur_write_int(savef, o->o_weight);
398 ur_write_char(savef, o->o_launch);
399 ur_write(savef, &o->o_mark[0], MARKLEN);
400 ur_write_long(savef, o->o_worth);
401
402 other = 0;
403
404 if (o->o_bag)
405 other = 1;
406 else if (o->next_obj)
407 other |= 2;
408
409 ur_write_int(savef,other);
410
411 if (o->o_bag)
412 ur_write_bag(savef,o->o_bag);
413 if (o->next_obj && (o->next_obj->l_prev == NULL) )
414 ur_write_object_stack(savef, o->next_obj);
415 }
416
417 struct object *
418 ur_read_object(FILE *savef)
419 {
420 struct object *o;
421 long id;
422 int other;
423
424 o = ur_alloc(sizeof(struct object));
425
426 if (o == NULL)
427 return(NULL);
428
429 memset(o,0,sizeof(struct object));
430
431 id = ur_read_long(savef);
432
433 assert(id == URS_OBJECT);
434
435 o->o_pos = ur_read_coord(savef);
436 o->o_text = ur_read_string(savef);
437 o->o_damage = ur_read_string(savef);
438 o->o_hurldmg = ur_read_string(savef);
439 o->o_flags = ur_read_long(savef);
440 o->ar_flags = ur_read_long(savef);
441 o->o_type = ur_read_char(savef);
442 o->o_ident = ur_read_int(savef);
443 o->o_count = ur_read_int(savef);
444 o->o_which = ur_read_int(savef);
445 o->o_hplus = ur_read_int(savef);
446 o->o_dplus = ur_read_int(savef);
447 o->o_ac = ur_read_int(savef);
448 o->o_group = ur_read_int(savef);
449 o->o_weight = ur_read_int(savef);
450 o->o_launch = ur_read_char(savef);
451 ur_read(savef, &o->o_mark[0], MARKLEN);
452 o->o_worth = ur_read_long(savef);
453
454 other = ur_read_int(savef);
455
456 if (other & 1)
457 o->o_bag = ur_read_bag(savef);
458 if (other & 2)
459 o->next_obj = ur_read_object_stack(savef);
460
461 return(o);
462 }
463
464 int
465 list_size(struct linked_list *l)
466 {
467 int cnt=0;
468
469 if (l == NULL)
470 return(0);
471
472 while(l != NULL)
473 {
474 cnt++;
475 l = l->l_next;
476 }
477
478 return(cnt);
479 }
480
481 int
482 find_thing_index(struct linked_list *l, struct thing *item)
483 {
484 int cnt=0;
485
486 if (l == NULL)
487 return(-1);
488
489 while(l != NULL)
490 {
491 if (item == l->data.th)
492 return(cnt+1);
493
494 cnt++;
495 l = l->l_next;
496 }
497
498 return(0);
499 }
500
501
502 int
503 find_list_index(struct linked_list *l, struct object *item)
504 {
505 int cnt=0;
506
507 if (l == NULL)
508 return(-1);
509
510 while(l != NULL)
511 {
512 if (item == l->data.obj)
513 return(cnt+1);
514
515 cnt++;
516 l = l->l_next;
517 }
518
519 return(0);
520 }
521
522 struct object *
523 find_object(struct linked_list *list, int num)
524 {
525 int cnt = 0;
526 struct linked_list *l = list;
527
528 if ( (num < 1) || (list == NULL) )
529 return(NULL);
530
531 num--;
532
533 for(cnt = 0; cnt < num; cnt++)
534 {
535 if ( l == NULL )
536 return(NULL);
537
538 l = l->l_next;
539 }
540
541 return(l->data.obj);
542 }
543
544 struct thing *
545 find_thing(struct linked_list *list, int num)
546 {
547 int cnt = 0;
548 struct linked_list *l = list;
549
550 if ( (num < 1) || (list == NULL) )
551 return(NULL);
552 num--;
553
554 for(cnt = 0; cnt < num; cnt++)
555 {
556 if (l == NULL)
557 return(NULL);
558
559 l = l->l_next;
560 }
561
562 return(l->data.th);
563 }
564
565
566 void
567 ur_write_object_stack(FILE *savef, struct linked_list *l)
568 {
569 int cnt;
570
571 ur_write_long(savef, URS_STACKOBJECT);
572
573 ur_write_int(savef, cnt = list_size(l) );
574
575 if (cnt == 0)
576 return;
577
578 while(l != NULL)
579 {
580 ur_write_object(savef, l->data.obj);
581 l = l->l_next;
582 }
583 }
584
585 void
586 ur_write_bag(FILE *savef, struct linked_list *l)
587 {
588 int cnt;
589
590 ur_write_long(savef, URS_BAGOBJECT);
591
592 ur_write_int(savef, cnt = list_size(l) );
593
594 if (cnt == 0)
595 return;
596
597 while(l != NULL)
598 {
599 ur_write_object(savef, l->data.obj);
600 l = l->l_next;
601 }
602 }
603
604 struct linked_list *
605 ur_read_object_stack(FILE *savef)
606 {
607 long id;
608 int i,cnt;
609 struct linked_list *l = NULL, *previous = NULL, *head = NULL;
610
611 id = ur_read_long(savef);
612
613 assert(id == URS_STACKOBJECT);
614
615 cnt = ur_read_int(savef);
616
617 for(i = 0; i < cnt; i++)
618 {
619 l = new_list();
620 l->l_prev = previous;
621
622 if (previous != NULL)
623 previous->l_next = l;
624
625 l->data.obj = ur_read_object(savef);
626
627 if (previous == NULL)
628 head = l;
629
630 previous = l;
631 }
632
633 if (l != NULL)
634 l->l_next = NULL;
635
636 return(head);
637 }
638
639
640 struct linked_list *
641 ur_read_bag(FILE *savef)
642 {
643 long id;
644 int i,cnt;
645 struct linked_list *l = NULL, *previous = NULL, *head = NULL;
646
647 id = ur_read_long(savef);
648
649 assert( id == URS_BAGOBJECT );
650
651 cnt = ur_read_int(savef);
652
653 for(i = 0; i < cnt; i++)
654 {
655 l = new_list();
656 l->l_prev = previous;
657
658 if (previous != NULL)
659 previous->l_next = l;
660
661 l->data.obj = ur_read_object(savef);
662
663 if (previous == NULL)
664 head = l;
665
666 previous = l;
667 }
668
669 if (l != NULL)
670 l->l_next = NULL;
671
672 return(head);
673 }
674
675 void
676 ur_fixup_monsters(struct linked_list *l)
677 {
678 while(l != NULL)
679 {
680 if (l->data.th->t_chasee == (void *) -1L)
681 l->data.th->t_chasee = &player;
682 else
683 l->data.th->t_chasee = find_thing(mlist, l->data.th->chasee_index);
684
685 l->data.th->t_horde = find_object(lvl_obj, l->data.th->horde_index);
686
687 l = l->l_next;
688 }
689 }
690
691 void
692 ur_write_monsters(FILE *savef, struct linked_list *l)
693 {
694 int cnt;
695
696 ur_write_long(savef, URS_MONSTERLIST);
697
698 cnt = list_size(l);
699
700 ur_write_int(savef, cnt);
701
702 if (cnt < 1)
703 return;
704
705 while(l != NULL)
706 {
707 ur_write_thing(savef, l->data.th);
708 l = l->l_next;
709 }
710 }
711
712 struct linked_list *
713 ur_read_monsters(FILE *savef)
714 {
715 long id;
716 int i,cnt;
717 struct linked_list *l=NULL, *previous = NULL, *head = NULL;
718
719 id = ur_read_long(savef);
720
721 assert(id == URS_MONSTERLIST);
722
723 cnt = ur_read_int(savef);
724
725 if (cnt == 0)
726 return(NULL);
727
728 for(i = 0; i < cnt; i++)
729 {
730 l = new_list();
731
732 l->l_prev = previous;
733
734 if (previous != NULL)
735 previous->l_next = l;
736
737 l->data.th = ur_read_thing(savef);
738
739 if (previous == NULL)
740 head = l;
741
742 previous = l;
743 }
744
745 if (l != NULL)
746 l->l_next = NULL;
747
748 return(head);
749 }
750
751 void
752 ur_write_monster_stats(FILE *savef, struct mstats *m)
753 {
754 ur_write_long(savef, URS_MONSTERSTATS);
755 ur_write_short(savef, m->s_str);
756 ur_write_long(savef, m->s_exp);
757 ur_write_int(savef, m->s_lvl);
758 ur_write_int(savef, m->s_arm);
759 ur_write_string(savef, m->s_hpt);
760 ur_write_string(savef, m->s_dmg);
761 }
762
763 struct mstats *
764 ur_read_monster_stats(FILE *savef)
765 {
766 long id;
767 struct mstats *m;
768
769 id = ur_read_long(savef);
770
771 assert(id == URS_MONSTERSTATS);
772
773 m = ur_alloc( sizeof(struct mstats) );
774
775 m->s_str = ur_read_short(savef);
776 m->s_exp = ur_read_long(savef);
777 m->s_lvl = ur_read_int(savef);
778 m->s_arm = ur_read_int(savef);
779 m->s_hpt = ur_read_string(savef);
780 m->s_dmg = ur_read_string(savef);
781
782 return(m);
783 }
784
785 void
786 ur_write_monster(FILE *savef, struct monster *m)
787 {
788 int i;
789
790 ur_write_long(savef, URS_MONSTER);
791 ur_write_string(savef, m->m_name);
792 ur_write_short(savef, m->m_carry);
793 ur_write_int(savef, m->m_normal);
794 ur_write_int(savef, m->m_wander);
795 ur_write_char(savef, m->m_appear);
796 ur_write_string(savef, m->m_intel);
797
798 for(i = 0; i < 10; i++)
799 ur_write_long(savef, m->m_flags[i]);
800
801 ur_write_string(savef, m->m_typesum);
802 ur_write_short(savef, m->m_numsum);
803 ur_write_short(savef, m->m_add_exp);
804 ur_write_monster_stats(savef, &m->m_stats);
805 }
806
807 struct monster *
808 ur_read_monster(FILE *savef)
809 {
810 struct monster *m;
811 struct mstats *mstats;
812
813 m = ur_alloc( sizeof(struct monster) );
814
815 m->m_name = ur_read_string(savef);
816 m->m_carry = ur_read_short(savef);
817 m->m_normal = ur_read_int(savef);
818 m->m_wander = ur_read_int(savef);
819 m->m_appear = ur_read_char(savef);
820 m->m_intel = ur_read_string(savef);
821 ur_read(savef, &m->m_flags[0], 10*sizeof(long));
822 m->m_typesum = ur_read_string(savef);
823 m->m_numsum = ur_read_short(savef);
824 m->m_add_exp = ur_read_short(savef);
825
826 mstats = ur_read_monster_stats(savef);
827
828 m->m_stats = *mstats;
829 ur_free(mstats);
830
831 return(m);
832 }
833
834 void
835 ur_write_trap(FILE *savef, struct trap *t)
836 {
837 ur_write_long(savef, URS_TRAP);
838 ur_write_coord(savef, t->tr_pos);
839 ur_write_long(savef, t->tr_flags);
840 ur_write_char(savef, t->tr_type);
841 ur_write_char(savef, t->tr_show);
842 }
843
844 struct trap *
845 ur_read_trap(FILE *savef)
846 {
847 struct trap *t;
848 long id;
849
850 id = ur_read_long(savef);
851
852 assert(id == URS_TRAP);
853
854 t = ur_alloc( sizeof(struct trap));
855
856 t->tr_pos = ur_read_coord(savef);
857 t->tr_flags = ur_read_long(savef);
858 t->tr_type = ur_read_char(savef);
859 t->tr_show = ur_read_char(savef);
860
861 return(t);
862 }
863
864 void
865 ur_write_stats(FILE *savef, struct stats *s)
866 {
867 ur_write_long(savef, URS_STATS);
868 ur_write_string(savef, s->s_dmg);
869 ur_write_long(savef, s->s_exp);
870 ur_write_int(savef, s->s_hpt);
871 ur_write_int(savef, s->s_pack);
872 ur_write_int(savef, s->s_carry);
873 ur_write_int(savef, s->s_lvl);
874 ur_write_int(savef, s->s_arm);
875 ur_write_int(savef, s->s_acmod);
876 ur_write_int(savef, s->s_power);
877 ur_write_int(savef, s->s_str);
878 ur_write_int(savef, s->s_intel);
879 ur_write_int(savef, s->s_wisdom);
880 ur_write_int(savef, s->s_dext);
881 ur_write_int(savef, s->s_const);
882 ur_write_int(savef, s->s_charisma);
883 }
884
885 struct stats *
886 ur_read_stats(FILE *savef)
887 {
888 struct stats *s;
889 long id;
890
891 id = ur_read_long(savef);
892
893 assert(id == URS_STATS);
894
895 s = ur_alloc(sizeof(struct stats));
896
897 s->s_dmg = ur_read_string(savef);
898 s->s_exp = ur_read_long(savef);
899 s->s_hpt = ur_read_int(savef);
900 s->s_pack = ur_read_int(savef);
901 s->s_carry = ur_read_int(savef);
902 s->s_lvl = ur_read_int(savef);
903 s->s_arm = ur_read_int(savef);
904 s->s_acmod = ur_read_int(savef);
905 s->s_power = ur_read_int(savef);
906 s->s_str = ur_read_int(savef);
907 s->s_intel = ur_read_int(savef);
908 s->s_wisdom = ur_read_int(savef);
909 s->s_dext = ur_read_int(savef);
910 s->s_const = ur_read_int(savef);
911 s->s_charisma = ur_read_int(savef);
912
913 return(s);
914 }
915
916 void
917 ur_write_thing(FILE *savef, struct thing *t)
918 {
919 int i;
920
921 ur_write_long(savef, URS_THING);
922 ur_write_bag(savef, t->t_pack);
923 ur_write_stats(savef, &t->t_stats);
924 ur_write_stats(savef, &t->maxstats);
925 ur_write_int(savef, t->t_ischasing);
926
927 if (t->t_chasee == &player)
928 ur_write_long(savef, -1L);
929 else if (t->t_chasee == NULL)
930 ur_write_long(savef, 0L);
931 else
932 {
933 long m;
934
935 m = find_thing_index(mlist, t->t_chasee);
936
937 ur_write_long(savef,m);
938 }
939
940 ur_write_long(savef, find_list_index(lvl_obj, t->t_horde));
941 ur_write_coord(savef, t->t_pos);
942 ur_write_coord(savef, t->t_oldpos);
943 ur_write_coord(savef, t->t_nxtpos);
944
945 for(i = 0; i < 16; i++)
946 ur_write_long(savef, t->t_flags[i]);
947
948 ur_write_int(savef, t->t_praycnt);
949 ur_write_int(savef, t->t_trans);
950 ur_write_int(savef, t->t_turn);
951 ur_write_int(savef, t->t_wasshot);
952 ur_write_int(savef, t->t_ctype);
953 ur_write_int(savef, t->t_index);
954 ur_write_int(savef, t->t_no_move);
955 ur_write_int(savef, t->t_rest_hpt);
956 ur_write_int(savef, t->t_rest_pow);
957 ur_write_int(savef, t->t_doorgoal);
958 ur_write_char(savef, t->t_type);
959 ur_write_char(savef, t->t_disguise);
960 ur_write_char(savef, t->t_oldch);
961 }
962
963 struct thing *
964 ur_read_thing(FILE *savef)
965 {
966 long id;
967 int i;
968 struct thing *t;
969 struct stats *s;
970
971 id = ur_read_long(savef);
972
973 assert(id == URS_THING);
974
975 t = ur_alloc( sizeof(struct thing) );
976
977 t->t_pack = ur_read_bag(savef);
978
979 s = ur_read_stats(savef);
980 t->t_stats = *s;
981 ur_free(s);
982
983 s = ur_read_stats(savef);
984 t->maxstats = *s;
985 ur_free(s);
986
987 t->t_ischasing = ur_read_int(savef);
988 t->chasee_index = ur_read_long(savef);
989 t->horde_index = ur_read_long(savef);
990 t->t_pos = ur_read_coord(savef);
991 t->t_oldpos = ur_read_coord(savef);
992 t->t_nxtpos = ur_read_coord(savef);
993
994 for(i = 0; i < 16; i++)
995 t->t_flags[i] = ur_read_long(savef);
996
997 t->t_praycnt = ur_read_int(savef);
998 t->t_trans = ur_read_int(savef);
999 t->t_turn = ur_read_int(savef);
1000 t->t_wasshot = ur_read_int(savef);
1001 t->t_ctype = ur_read_int(savef);
1002 t->t_index = ur_read_int(savef);
1003 t->t_no_move = ur_read_int(savef);
1004 t->t_rest_hpt = ur_read_int(savef);
1005 t->t_rest_pow = ur_read_int(savef);
1006 t->t_doorgoal = ur_read_int(savef);
1007 t->t_type = ur_read_char(savef);
1008 t->t_disguise = ur_read_char(savef);
1009 t->t_oldch = ur_read_char(savef);
1010
1011 return(t);
1012 }
1013
1014 void
1015 ur_write_window(FILE *savef, WINDOW *win)
1016 {
1017 int i,j;
1018
1019 ur_write_long(savef, URS_WINDOW);
1020
1021 ur_write_int(savef, win->_maxy);
1022 ur_write_int(savef, win->_maxx);
1023
1024 for(i=0; i < win->_maxy; i++)
1025 for(j = 0; j < win->_maxx; j++)
1026 ur_write_ulong(savef, mvwinch(win,i,j));
1027 }
1028
1029 void
1030 ur_read_window(FILE *savef, WINDOW *win)
1031 {
1032 int i,j;
1033 int maxy, maxx;
1034 long id;
1035
1036 id = ur_read_long(savef);
1037
1038 assert(id == URS_WINDOW);
1039
1040 maxy = ur_read_int(savef);
1041 maxx = ur_read_int(savef);
1042
1043 for(i=0; i < maxy; i++)
1044 for(j = 0; j < maxx; j++)
1045 mvwaddch(win,i,j,ur_read_long(savef));
1046 }
1047
1048 void
1049 ur_write_daemons(FILE *savef)
1050 {
1051 int i;
1052 int id=0;
1053
1054 ur_write_long(savef, URS_DAEMONS);
1055
1056 for(i = 0; i < MAXDAEMONS; i++)
1057 {
1058 ur_write_int(savef, d_list[i].d_type );
1059 ur_write_int(savef, d_list[i].d_when );
1060 ur_write_int(savef, d_list[i].d_id);
1061
1062 if (d_list[i].d_id == FUSE_UNSUMMON)
1063 id = find_thing_index(mlist, d_list[i].d_arg);
1064
1065 if (d_list[i].d_id == DAEMON_DOCTOR)
1066 id = find_thing_index(mlist, d_list[i].d_arg);
1067
1068 ur_write_int(savef, id);
1069 ur_write_int(savef, d_list[i].d_time );
1070 }
1071 }
1072
1073 void
1074 ur_read_daemons(FILE *savef)
1075 {
1076 long id;
1077 int i;
1078 demoncnt = 0;
1079
1080 id = ur_read_long(savef);
1081
1082 assert(id == URS_DAEMONS);
1083
1084 for(i = 0; i < MAXDAEMONS; i++)
1085 {
1086 d_list[i].d_type = ur_read_int(savef);
1087 d_list[i].d_when = ur_read_int(savef);
1088 d_list[i].d_id = ur_read_int(savef);
1089 id = ur_read_int(savef);
1090 d_list[i].d_time = ur_read_int(savef);
1091
1092 if ((d_list[i].d_type != EMPTY) && (d_list[i].d_id == FUSE_UNSUMMON))
1093 {
1094 d_list[i].d_arg = find_thing(mlist,id);
1095
1096 if (d_list[i].d_arg == NULL)
1097 d_list[i].d_type = EMPTY;
1098 }
1099
1100 if ((d_list[i].d_type != EMPTY) && (d_list[i].d_id == DAEMON_DOCTOR) )
1101 {
1102 if (id == 0)
1103 d_list[i].d_arg = &player;
1104 else
1105 d_list[i].d_arg = find_thing(mlist, id);
1106
1107 if (d_list[i].d_arg == NULL)
1108 d_list[i].d_type = EMPTY;
1109 }
1110
1111 if (d_list[i].d_type != EMPTY)
1112 demoncnt++;
1113 }
1114 }
1115
1116 void
1117 save_file(FILE *savef)
1118 {
1119 int i,weapon,armor,ring=0,room= -1,monster;
1120
1121 ur_write_string(savef, save_format);
1122
1123 ur_write_string(savef,"\nScroll Names\n");
1124 for(i = 0; i < MAXSCROLLS; i++)
1125 ur_write_string(savef,s_names[i]);
1126
1127 ur_write_string(savef,"\nPotion Colors\n");
1128 for(i = 0; i < MAXPOTIONS; i++)
1129 ur_write_string(savef,p_colors[i]);
1130
1131 ur_write_string(savef,"\nRing Stones\n");
1132 for(i = 0; i < MAXRINGS; i++)
1133 ur_write_string(savef,r_stones[i]);
1134
1135 ur_write_string(savef,"\nStick types\n");
1136 for(i = 0; i < MAXSTICKS; i++)
1137 ur_write_string(savef,ws_made[i]);
1138
1139 ur_write_string(savef,"\nStick types\n");
1140 for(i = 0; i < MAXSTICKS; i++)
1141 ur_write_string(savef,ws_type[i]);
1142
1143 ur_write_string(savef, "\nTraps on this level\n");
1144 ur_write_int(savef, MAXTRAPS);
1145 for(i = 0; i < MAXTRAPS; i++)
1146 ur_write_trap(savef, &traps[i]);
1147
1148 ur_write_string(savef,"\nRooms on this level\n");
1149 ur_write_int(savef, MAXROOMS);
1150 for(i = 0; i < MAXROOMS; i++)
1151 {
1152 ur_write_room(savef, &rooms[i]);
1153
1154 if (&rooms[i] == oldrp)
1155 room = i;
1156 }
1157 ur_write_int(savef,room); /* save for recovery of oldrp */
1158
1159 ur_write_string(savef,"\nThe Rogue\n");
1160 ur_write_thing(savef, &player);
1161
1162 ur_write_string(savef,"\nObjects on this level\n");
1163 ur_write_bag(savef, lvl_obj);
1164
1165 ur_write_string(savef,"\nRogue's Familiar, if any \n");
1166 ur_write_monsters(savef, fam_ptr);
1167
1168 ur_write_string(savef,"\nMonsters on this level\n");
1169 ur_write_monsters(savef, mlist);
1170
1171 monster = find_thing_index(mlist, beast);
1172 ur_write_int(savef, monster);
1173
1174 ur_write_string(savef,"\nItems in use by rogue\n");
1175 weapon = find_list_index(player.t_pack, cur_weapon);
1176 armor = find_list_index(player.t_pack, cur_armor);
1177 ur_write_int(savef, weapon);
1178 ur_write_int(savef, armor);
1179
1180 for(i=0; i < 10; i++)
1181 {
1182 if (cur_ring[i] == NULL)
1183 ring = find_list_index(player.t_pack, cur_ring[i]);
1184
1185 ur_write_int(savef, ring);
1186 }
1187
1188 ur_write_string(savef,"\nActive Daemons and Fuses\n");
1189 ur_write_daemons(savef);
1190
1191 ur_write_string(savef, "\nMisc\n");
1192
1193 for(i = 0; i < 10; i++)
1194 ur_write_string(savef, msgbuf[i]);
1195
1196 ur_write_int(savef, msg_index);
1197 ur_write_int(savef, foodlev);
1198 ur_write_int(savef, ntraps);
1199 ur_write_int(savef, dnum);
1200 ur_write_int(savef, max_level);
1201 ur_write_int(savef, lost_dext);
1202 ur_write_int(savef, no_command);
1203 ur_write_int(savef, level);
1204 ur_write_int(savef, see_dist);
1205 ur_write_int(savef, no_food);
1206 ur_write_int(savef, count);
1207 ur_write_int(savef, food_left);
1208 ur_write_int(savef, group);
1209 ur_write_int(savef, hungry_state);
1210 ur_write_int(savef, infest_dam);
1211 ur_write_int(savef, lost_str);
1212 ur_write_int(savef, hold_count);
1213 ur_write_int(savef, trap_tries);
1214 ur_write_int(savef, has_artifact);
1215 ur_write_int(savef, picked_artifact);
1216 ur_write_int(savef, luck);
1217 ur_write_int(savef, resurrect);
1218 ur_write_int(savef, fam_type);
1219 ur_write_int(savef, mons_summoned);
1220 ur_write_char(savef, PLAYER);
1221 ur_write_char(savef, take);
1222 ur_write_char(savef, runch);
1223 ur_write_int(savef, char_type);
1224 ur_write_int(savef, inv_type);
1225 ur_write_int(savef, pool_teleport);
1226 ur_write_int(savef, inwhgt);
1227 ur_write_int(savef, after);
1228 ur_write_int(savef, waswizard);
1229 ur_write_int(savef, canwizard);
1230 ur_write_int(savef, playing);
1231 ur_write_int(savef, running);
1232 ur_write_int(savef, fighting);
1233 ur_write_int(savef, wizard);
1234 ur_write_int(savef, wiz_verbose);
1235 ur_write_int(savef, moving);
1236 ur_write_coord(savef, delta);
1237 ur_write_int(savef, levtype);
1238 ur_write_int(savef, purse);
1239 ur_write_int(savef, total);
1240 ur_write_window(savef, cw);
1241 ur_write_window(savef, hw);
1242 ur_write_window(savef, mw);
1243 ur_write_window(savef, stdscr);
1244
1245 ur_write_string(savef,"\nGame Options\n");
1246 ur_write_int(savef, terse);
1247 ur_write_int(savef, door_stop);
1248 ur_write_int(savef, doorstop);
1249 ur_write_int(savef, jump);
1250 ur_write_int(savef, firstmove);
1251 ur_write_int(savef, askme);
1252 ur_write_string(savef,whoami);
1253 ur_write_string(savef,fruit);
1254 ur_write_string(savef,file_name);
1255 ur_write_string(savef,score_file);
1256
1257 ur_write_string(savef,"\nEnd of UltraRogue Game State\n");
1258 }
1259
1260 #define DUMPSTRING { str = ur_read_string(savef); /*printf("%s",str);*/ ur_free(str); }
1261
1262 int
1263 restore_file(FILE *savef)
1264 {
1265 int i,j;
1266 char *str;
1267 struct trap *t;
1268 struct room *r;
1269 struct thing *p;
1270
1271 str = ur_read_string(savef);
1272
1273 if (strcmp(str, save_format) != 0)
1274 {
1275 printf("Save Game Version: %s\n", str);
1276 printf("Real Game Version: %s\n", save_format);
1277 printf("Sorry, versions don't match.\n");
1278 return(FALSE);
1279 }
1280
1281 DUMPSTRING
1282 for(i=0; i < MAXSCROLLS; i++)
1283 s_names[i] = ur_read_string(savef);
1284
1285 DUMPSTRING
1286 for(i=0; i < MAXPOTIONS; i++)
1287 p_colors[i] = ur_read_string(savef);
1288
1289 DUMPSTRING
1290 for(i=0; i < MAXRINGS; i++)
1291 r_stones[i] = ur_read_string(savef);
1292
1293 DUMPSTRING
1294 for(i=0; i < MAXSTICKS; i++)
1295 ws_made[i] = ur_read_string(savef);
1296
1297 DUMPSTRING
1298 for(i=0; i < MAXSTICKS; i++)
1299 ws_type[i] = ur_read_string(savef);
1300
1301 DUMPSTRING
1302 i = ur_read_int(savef);
1303 assert(i == MAXTRAPS);
1304
1305 for(i=0;i<MAXTRAPS;i++)
1306 {
1307 t = ur_read_trap(savef);
1308 traps[i] = *t;
1309 ur_free(t);
1310 }
1311
1312 DUMPSTRING
1313 i = ur_read_int(savef);
1314 assert(i == MAXROOMS);
1315
1316 for(i=0;i<MAXROOMS;i++)
1317 {
1318 r = ur_read_room(savef);
1319 rooms[i] = *r;
1320 ur_free(r);
1321 }
1322 i = ur_read_int(savef);
1323 oldrp = &rooms[i];
1324
1325 DUMPSTRING
1326 p = ur_read_thing(savef);
1327 player = *p;
1328 ur_free(p);
1329
1330 DUMPSTRING
1331 lvl_obj = ur_read_bag(savef);
1332
1333 DUMPSTRING
1334 fam_ptr = ur_read_monsters(savef);
1335
1336 DUMPSTRING
1337 mlist = ur_read_monsters(savef);
1338 i = ur_read_int(savef);
1339 beast = find_thing(mlist, i);
1340
1341 ur_fixup_monsters(fam_ptr);
1342 ur_fixup_monsters(fam_ptr);
1343
1344 DUMPSTRING
1345 i = ur_read_int(savef);
1346 cur_weapon = find_object(player.t_pack, i);
1347
1348 i = ur_read_int(savef);
1349 cur_armor = find_object(player.t_pack, i);
1350
1351 for(j=0; j < 10; j++)
1352 {
1353 i = ur_read_int(savef);
1354 if (i == -1)
1355 cur_ring[j] = NULL;
1356 else
1357 cur_ring[j] = find_object(player.t_pack, i);
1358 }
1359
1360 DUMPSTRING
1361 ur_read_daemons(savef);
1362
1363 DUMPSTRING
1364 for(i = 0; i < 10; i++)
1365 {
1366 str = ur_read_string(savef);
1367 strcpy(&msgbuf[i][0],str);
1368 ur_free(str);
1369 }
1370
1371 msg_index = ur_read_int(savef);
1372
1373 foodlev = ur_read_int(savef);
1374 ntraps = ur_read_int(savef);
1375 dnum = ur_read_int(savef);
1376 max_level = ur_read_int(savef);
1377 lost_dext = ur_read_int(savef);
1378 no_command = ur_read_int(savef);
1379 level = ur_read_int(savef);
1380 see_dist = ur_read_int(savef);
1381 no_food = ur_read_int(savef);
1382 count = ur_read_int(savef);
1383 food_left = ur_read_int(savef);
1384 group = ur_read_int(savef);
1385 hungry_state = ur_read_int(savef);
1386 infest_dam = ur_read_int(savef);
1387 lost_str = ur_read_int(savef);
1388 hold_count = ur_read_int(savef);
1389 trap_tries = ur_read_int(savef);
1390 has_artifact = ur_read_int(savef);
1391 picked_artifact = ur_read_int(savef);
1392 luck = ur_read_int(savef);
1393 resurrect = ur_read_int(savef);
1394 fam_type = ur_read_int(savef);
1395 mons_summoned = ur_read_int(savef);
1396 PLAYER = ur_read_char(savef);
1397 take = ur_read_char(savef);
1398 runch = ur_read_char(savef);
1399 char_type = ur_read_int(savef);
1400 inv_type = ur_read_int(savef);
1401 pool_teleport = ur_read_int(savef);
1402 inwhgt = ur_read_int(savef);
1403 after = ur_read_int(savef);
1404 waswizard = ur_read_int(savef);
1405 canwizard = ur_read_int(savef);
1406 playing = ur_read_int(savef);
1407 running = ur_read_int(savef);
1408 fighting = ur_read_int(savef);
1409 wizard = ur_read_int(savef);
1410 wiz_verbose = ur_read_int(savef);
1411 moving = ur_read_int(savef);
1412 delta = ur_read_coord(savef);
1413 levtype = ur_read_int(savef);
1414 purse = ur_read_int(savef);
1415 total = ur_read_int(savef);
1416 ur_read_window(savef, cw);
1417 ur_read_window(savef, hw);
1418 ur_read_window(savef, mw);
1419 ur_read_window(savef, stdscr);
1420
1421 DUMPSTRING
1422 terse = ur_read_int(savef);
1423 door_stop = ur_read_int(savef);
1424 doorstop = ur_read_int(savef);
1425 jump = ur_read_int(savef);
1426 firstmove = ur_read_int(savef);
1427 askme = ur_read_int(savef);
1428 str = ur_read_string(savef);
1429 strcpy(whoami,str);
1430 ur_free(str);
1431 str = ur_read_string(savef);
1432 strcpy(fruit,str);
1433 ur_free(str);
1434 str = ur_read_string(savef);
1435 strcpy(file_name,str);
1436 ur_free(str);
1437 str = ur_read_string(savef);
1438 strcpy(score_file,str);
1439 ur_free(str);
1440
1441 DUMPSTRING
1442 return(TRUE);
1443 }
1444
1445