OSDN Git Service

Extract Process per 100 energy. Now it contains music and hex upkeep effects.
[hengband/hengband.git] / src / save.c
1 /* File: save.c */
2
3 /*
4  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
5  *
6  * This software may be copied and distributed for educational, research,
7  * and not for profit purposes provided that this copyright and statement
8  * are included in all such copies.  Other copyrights may also apply.
9  */
10
11 /* Purpose: interact with savefiles */
12
13 #include "angband.h"
14
15
16
17 /*
18  * Some "local" parameters, used to help write savefiles
19  */
20
21 static FILE     *fff;           /* Current save "file" */
22
23 static byte     xor_byte;       /* Simple encryption */
24
25 static u32b     v_stamp = 0L;   /* A simple "checksum" on the actual values */
26 static u32b     x_stamp = 0L;   /* A simple "checksum" on the encoded bytes */
27
28
29
30 /*
31  * These functions place information into a savefile a byte at a time
32  */
33
34 static void sf_put(byte v)
35 {
36         /* Encode the value, write a character */
37         xor_byte ^= v;
38         (void)putc((int)xor_byte, fff);
39
40         /* Maintain the checksum info */
41         v_stamp += v;
42         x_stamp += xor_byte;
43 }
44
45 static void wr_byte(byte v)
46 {
47         sf_put(v);
48 }
49
50 static void wr_u16b(u16b v)
51 {
52         sf_put((byte)(v & 0xFF));
53         sf_put((byte)((v >> 8) & 0xFF));
54 }
55
56 static void wr_s16b(s16b v)
57 {
58         wr_u16b((u16b)v);
59 }
60
61 static void wr_u32b(u32b v)
62 {
63         sf_put((byte)(v & 0xFF));
64         sf_put((byte)((v >> 8) & 0xFF));
65         sf_put((byte)((v >> 16) & 0xFF));
66         sf_put((byte)((v >> 24) & 0xFF));
67 }
68
69 static void wr_s32b(s32b v)
70 {
71         wr_u32b((u32b)v);
72 }
73
74 static void wr_string(cptr str)
75 {
76         while (*str)
77         {
78                 wr_byte(*str);
79                 str++;
80         }
81         wr_byte(*str);
82 }
83
84
85 /*
86  * These functions write info in larger logical records
87  */
88
89
90 /*
91  * Write an "item" record
92  */
93 static void wr_item(object_type *o_ptr)
94 {
95         u32b flags = 0x00000000;
96
97         if (o_ptr->pval) flags |= SAVE_ITEM_PVAL;
98         if (o_ptr->discount) flags |= SAVE_ITEM_DISCOUNT;
99         if (o_ptr->number != 1) flags |= SAVE_ITEM_NUMBER;
100         if (o_ptr->name1) flags |= SAVE_ITEM_NAME1;
101         if (o_ptr->name2) flags |= SAVE_ITEM_NAME2;
102         if (o_ptr->timeout) flags |= SAVE_ITEM_TIMEOUT;
103         if (o_ptr->to_h) flags |= SAVE_ITEM_TO_H;
104         if (o_ptr->to_d) flags |= SAVE_ITEM_TO_D;
105         if (o_ptr->to_a) flags |= SAVE_ITEM_TO_A;
106         if (o_ptr->ac) flags |= SAVE_ITEM_AC;
107         if (o_ptr->dd) flags |= SAVE_ITEM_DD;
108         if (o_ptr->ds) flags |= SAVE_ITEM_DS;
109         if (o_ptr->ident) flags |= SAVE_ITEM_IDENT;
110         if (o_ptr->marked) flags |= SAVE_ITEM_MARKED;
111         if (o_ptr->art_flags[0]) flags |= SAVE_ITEM_ART_FLAGS0;
112         if (o_ptr->art_flags[1]) flags |= SAVE_ITEM_ART_FLAGS1;
113         if (o_ptr->art_flags[2]) flags |= SAVE_ITEM_ART_FLAGS2;
114         if (o_ptr->art_flags[3]) flags |= SAVE_ITEM_ART_FLAGS3;
115         if (o_ptr->curse_flags) flags |= SAVE_ITEM_CURSE_FLAGS;
116         if (o_ptr->held_m_idx) flags |= SAVE_ITEM_HELD_M_IDX;
117         if (o_ptr->xtra1) flags |= SAVE_ITEM_XTRA1;
118         if (o_ptr->xtra2) flags |= SAVE_ITEM_XTRA2;
119         if (o_ptr->xtra3) flags |= SAVE_ITEM_XTRA3;
120         if (o_ptr->xtra4) flags |= SAVE_ITEM_XTRA4;
121         if (o_ptr->xtra5) flags |= SAVE_ITEM_XTRA5;
122         if (o_ptr->feeling) flags |= SAVE_ITEM_FEELING;
123         if (o_ptr->inscription) flags |= SAVE_ITEM_INSCRIPTION;
124         if (o_ptr->art_name) flags |= SAVE_ITEM_ART_NAME;
125
126         /*** Item save flags ***/
127         wr_u32b(flags);
128
129         /*** Write only un-obvious elements ***/
130         wr_s16b(o_ptr->k_idx);
131
132         /* Location */
133         wr_byte(o_ptr->iy);
134         wr_byte(o_ptr->ix);
135
136         if (flags & SAVE_ITEM_PVAL) wr_s16b(o_ptr->pval);
137
138         if (flags & SAVE_ITEM_DISCOUNT) wr_byte(o_ptr->discount);
139         if (flags & SAVE_ITEM_NUMBER) wr_byte(o_ptr->number);
140
141         wr_s16b(o_ptr->weight);
142
143         if (flags & SAVE_ITEM_NAME1) wr_byte(o_ptr->name1);
144         if (flags & SAVE_ITEM_NAME2) wr_byte(o_ptr->name2);
145         if (flags & SAVE_ITEM_TIMEOUT) wr_s16b(o_ptr->timeout);
146
147         if (flags & SAVE_ITEM_TO_H) wr_s16b(o_ptr->to_h);
148         if (flags & SAVE_ITEM_TO_D) wr_s16b(o_ptr->to_d);
149         if (flags & SAVE_ITEM_TO_A) wr_s16b(o_ptr->to_a);
150         if (flags & SAVE_ITEM_AC) wr_s16b(o_ptr->ac);
151         if (flags & SAVE_ITEM_DD) wr_byte(o_ptr->dd);
152         if (flags & SAVE_ITEM_DS) wr_byte(o_ptr->ds);
153
154         if (flags & SAVE_ITEM_IDENT) wr_byte(o_ptr->ident);
155
156         if (flags & SAVE_ITEM_MARKED) wr_byte(o_ptr->marked);
157
158         if (flags & SAVE_ITEM_ART_FLAGS0) wr_u32b(o_ptr->art_flags[0]);
159         if (flags & SAVE_ITEM_ART_FLAGS1) wr_u32b(o_ptr->art_flags[1]);
160         if (flags & SAVE_ITEM_ART_FLAGS2) wr_u32b(o_ptr->art_flags[2]);
161         if (flags & SAVE_ITEM_ART_FLAGS3) wr_u32b(o_ptr->art_flags[3]);
162
163         if (flags & SAVE_ITEM_CURSE_FLAGS) wr_u32b(o_ptr->curse_flags);
164
165         /* Held by monster index */
166         if (flags & SAVE_ITEM_HELD_M_IDX) wr_s16b(o_ptr->held_m_idx);
167
168         /* Extra information */
169         if (flags & SAVE_ITEM_XTRA1) wr_byte(o_ptr->xtra1);
170         if (flags & SAVE_ITEM_XTRA2) wr_byte(o_ptr->xtra2);
171         if (flags & SAVE_ITEM_XTRA3) wr_byte(o_ptr->xtra3);
172         if (flags & SAVE_ITEM_XTRA4) wr_s16b(o_ptr->xtra4);
173         if (flags & SAVE_ITEM_XTRA5) wr_s16b(o_ptr->xtra5);
174
175         /* Feelings */
176         if (flags & SAVE_ITEM_FEELING) wr_byte(o_ptr->feeling);
177
178         if (flags & SAVE_ITEM_INSCRIPTION) wr_string(quark_str(o_ptr->inscription));
179         if (flags & SAVE_ITEM_ART_NAME) wr_string(quark_str(o_ptr->art_name));
180 }
181
182
183 /*
184  * Write a "monster" record
185  */
186 static void wr_monster(monster_type *m_ptr)
187 {
188         u32b flags = 0x00000000;
189         byte tmp8u;
190
191         if (!is_original_ap(m_ptr)) flags |= SAVE_MON_AP_R_IDX;
192         if (m_ptr->sub_align) flags |= SAVE_MON_SUB_ALIGN;
193         if (MON_CSLEEP(m_ptr)) flags |= SAVE_MON_CSLEEP;
194         if (MON_FAST(m_ptr)) flags |= SAVE_MON_FAST;
195         if (MON_SLOW(m_ptr)) flags |= SAVE_MON_SLOW;
196         if (MON_STUNNED(m_ptr)) flags |= SAVE_MON_STUNNED;
197         if (MON_CONFUSED(m_ptr)) flags |= SAVE_MON_CONFUSED;
198         if (MON_MONFEAR(m_ptr)) flags |= SAVE_MON_MONFEAR;
199         if (m_ptr->target_y) flags |= SAVE_MON_TARGET_Y;
200         if (m_ptr->target_x) flags |= SAVE_MON_TARGET_X;
201         if (MON_INVULNER(m_ptr)) flags |= SAVE_MON_INVULNER;
202         if (m_ptr->smart) flags |= SAVE_MON_SMART;
203         if (m_ptr->exp) flags |= SAVE_MON_EXP;
204         if (m_ptr->mflag2) flags |= SAVE_MON_MFLAG2;
205         if (m_ptr->nickname) flags |= SAVE_MON_NICKNAME;
206         if (m_ptr->parent_m_idx) flags |= SAVE_MON_PARENT;
207
208         /*** Monster save flags ***/
209         wr_u32b(flags);
210
211         /*** Write only un-obvious elements ***/
212         wr_s16b(m_ptr->r_idx);
213         wr_byte(m_ptr->fy);
214         wr_byte(m_ptr->fx);
215         wr_s16b(m_ptr->hp);
216         wr_s16b(m_ptr->maxhp);
217         wr_s16b(m_ptr->max_maxhp);
218
219         /* Monster race index of its appearance */
220         if (flags & SAVE_MON_AP_R_IDX) wr_s16b(m_ptr->ap_r_idx);
221
222         if (flags & SAVE_MON_SUB_ALIGN) wr_byte(m_ptr->sub_align);
223         if (flags & SAVE_MON_CSLEEP) wr_s16b(m_ptr->mtimed[MTIMED_CSLEEP]);
224
225         wr_byte(m_ptr->mspeed);
226         wr_s16b(m_ptr->energy_need);
227
228         if (flags & SAVE_MON_FAST)
229         {
230                 tmp8u = (byte)m_ptr->mtimed[MTIMED_FAST];
231                 wr_byte(tmp8u);
232         }
233         if (flags & SAVE_MON_SLOW)
234         {
235                 tmp8u = (byte)m_ptr->mtimed[MTIMED_SLOW];
236                 wr_byte(tmp8u);
237         }
238         if (flags & SAVE_MON_STUNNED)
239         {
240                 tmp8u = (byte)m_ptr->mtimed[MTIMED_STUNNED];
241                 wr_byte(tmp8u);
242         }
243         if (flags & SAVE_MON_CONFUSED)
244         {
245                 tmp8u = (byte)m_ptr->mtimed[MTIMED_CONFUSED];
246                 wr_byte(tmp8u);
247         }
248         if (flags & SAVE_MON_MONFEAR)
249         {
250                 tmp8u = (byte)m_ptr->mtimed[MTIMED_MONFEAR];
251                 wr_byte(tmp8u);
252         }
253         if (flags & SAVE_MON_TARGET_Y) wr_s16b(m_ptr->target_y);
254         if (flags & SAVE_MON_TARGET_X) wr_s16b(m_ptr->target_x);
255         if (flags & SAVE_MON_INVULNER)
256         {
257                 tmp8u = (byte)m_ptr->mtimed[MTIMED_INVULNER];
258                 wr_byte(tmp8u);
259         }
260         if (flags & SAVE_MON_SMART) wr_u32b(m_ptr->smart);
261         if (flags & SAVE_MON_EXP) wr_u32b(m_ptr->exp);
262         if (flags & SAVE_MON_MFLAG2) wr_byte(m_ptr->mflag2);
263         if (flags & SAVE_MON_NICKNAME) wr_string(quark_str(m_ptr->nickname));
264         if (flags & SAVE_MON_PARENT) wr_s16b(m_ptr->parent_m_idx);
265 }
266
267
268 /*
269  * Write a "lore" record
270  */
271 static void wr_lore(int r_idx)
272 {
273         monster_race *r_ptr = &r_info[r_idx];
274
275         /* Count sights/deaths/kills */
276         wr_s16b(r_ptr->r_sights);
277         wr_s16b(r_ptr->r_deaths);
278         wr_s16b(r_ptr->r_pkills);
279         wr_s16b(r_ptr->r_akills);
280         wr_s16b(r_ptr->r_tkills);
281
282         /* Count wakes and ignores */
283         wr_byte(r_ptr->r_wake);
284         wr_byte(r_ptr->r_ignore);
285
286         /* Extra stuff */
287         wr_byte(r_ptr->r_xtra1);
288         wr_byte(r_ptr->r_xtra2);
289
290         /* Count drops */
291         wr_byte(r_ptr->r_drop_gold);
292         wr_byte(r_ptr->r_drop_item);
293
294         /* Count spells */
295         wr_byte(0); /* unused now */
296         wr_byte(r_ptr->r_cast_spell);
297
298         /* Count blows of each type */
299         wr_byte(r_ptr->r_blows[0]);
300         wr_byte(r_ptr->r_blows[1]);
301         wr_byte(r_ptr->r_blows[2]);
302         wr_byte(r_ptr->r_blows[3]);
303
304         /* Memorize flags */
305         wr_u32b(r_ptr->r_flags1);
306         wr_u32b(r_ptr->r_flags2);
307         wr_u32b(r_ptr->r_flags3);
308         wr_u32b(r_ptr->r_flags4);
309         wr_u32b(r_ptr->r_flags5);
310         wr_u32b(r_ptr->r_flags6);
311         wr_u32b(r_ptr->r_flagsr);
312
313
314         /* Monster limit per level */
315         wr_byte(r_ptr->max_num);
316
317         /* Location in saved floor */
318         wr_s16b(r_ptr->floor_id);
319
320         /* Later (?) */
321         wr_byte(0);
322 }
323
324
325 /*
326  * Write an "xtra" record
327  */
328 static void wr_xtra(int k_idx)
329 {
330         byte tmp8u = 0;
331
332         object_kind *k_ptr = &k_info[k_idx];
333
334         if (k_ptr->aware) tmp8u |= 0x01;
335         if (k_ptr->tried) tmp8u |= 0x02;
336
337         wr_byte(tmp8u);
338 }
339
340
341 /*
342  * Write a "store" record
343  */
344 static void wr_store(store_type *st_ptr)
345 {
346         int j;
347
348         /* Save the "open" counter */
349         wr_u32b(st_ptr->store_open);
350
351         /* Save the "insults" */
352         wr_s16b(st_ptr->insult_cur);
353
354         /* Save the current owner */
355         wr_byte(st_ptr->owner);
356
357         /* Save the stock size */
358         wr_s16b(st_ptr->stock_num);
359
360         /* Save the "haggle" info */
361         wr_s16b(st_ptr->good_buy);
362         wr_s16b(st_ptr->bad_buy);
363
364         wr_s32b(st_ptr->last_visit);
365
366         /* Save the stock */
367         for (j = 0; j < st_ptr->stock_num; j++)
368         {
369                 /* Save each item in stock */
370                 wr_item(&st_ptr->stock[j]);
371         }
372 }
373
374
375 /*
376  * Write RNG state
377  */
378 static errr wr_randomizer(void)
379 {
380         int i;
381
382         /* Zero */
383         wr_u16b(0);
384
385         /* Place */
386         wr_u16b(Rand_place);
387
388         /* State */
389         for (i = 0; i < RAND_DEG; i++)
390         {
391                 wr_u32b(Rand_state[i]);
392         }
393
394         /* Success */
395         return (0);
396 }
397
398
399 /*
400  * Write the "options"
401  */
402 static void wr_options(void)
403 {
404         int i;
405
406         u16b c;
407
408
409         /*** Oops ***/
410
411         /* Oops */
412         for (i = 0; i < 4; i++) wr_u32b(0L);
413
414
415         /*** Special Options ***/
416
417         /* Write "delay_factor" */
418         wr_byte(delay_factor);
419
420         /* Write "hitpoint_warn" */
421         wr_byte(hitpoint_warn);
422
423         /* Write "mana_warn" */
424         wr_byte(mana_warn);
425
426         /*** Cheating options ***/
427
428         c = 0;
429
430         if (p_ptr->wizard) c |= 0x0002;
431
432         if (cheat_peek) c |= 0x0100;
433         if (cheat_hear) c |= 0x0200;
434         if (cheat_room) c |= 0x0400;
435         if (cheat_xtra) c |= 0x0800;
436         if (cheat_know) c |= 0x1000;
437         if (cheat_live) c |= 0x2000;
438         if (cheat_save) c |= 0x4000;
439
440         wr_u16b(c);
441
442         /* Autosave info */
443         wr_byte(autosave_l);
444         wr_byte(autosave_t);
445         wr_s16b(autosave_freq);
446
447         /*** Extract options ***/
448
449         /* Analyze the options */
450         for (i = 0; option_info[i].o_desc; i++)
451         {
452                 int os = option_info[i].o_set;
453                 int ob = option_info[i].o_bit;
454
455                 /* Process real entries */
456                 if (option_info[i].o_var)
457                 {
458                         /* Set */
459                         if (*option_info[i].o_var)
460                         {
461                                 /* Set */
462                                 option_flag[os] |= (1L << ob);
463                         }
464
465                         /* Clear */
466                         else
467                         {
468                                 /* Clear */
469                                 option_flag[os] &= ~(1L << ob);
470                         }
471                 }
472         }
473
474
475         /*** Normal options ***/
476
477         /* Dump the flags */
478         for (i = 0; i < 8; i++) wr_u32b(option_flag[i]);
479
480         /* Dump the masks */
481         for (i = 0; i < 8; i++) wr_u32b(option_mask[i]);
482
483
484         /*** Window options ***/
485
486         /* Dump the flags */
487         for (i = 0; i < 8; i++) wr_u32b(window_flag[i]);
488
489         /* Dump the masks */
490         for (i = 0; i < 8; i++) wr_u32b(window_mask[i]);
491 }
492
493
494 /*
495  * Hack -- Write the "ghost" info
496  */
497 static void wr_ghost(void)
498 {
499         int i;
500
501         /* Name */
502 #ifdef JP
503         wr_string("ÉÔÀµ¤Ê¥´¡¼¥¹¥È");
504 #else
505         wr_string("Broken Ghost");
506 #endif
507
508
509         /* Hack -- stupid data */
510         for (i = 0; i < 60; i++) wr_byte(0);
511 }
512
513
514 /*
515  * Save quick start data
516  */
517 static void save_quick_start(void)
518 {
519         int i;
520
521         wr_byte(previous_char.psex);
522         wr_byte(previous_char.prace);
523         wr_byte(previous_char.pclass);
524         wr_byte(previous_char.pseikaku);
525         wr_byte(previous_char.realm1);
526         wr_byte(previous_char.realm2);
527
528         wr_s16b(previous_char.age);
529         wr_s16b(previous_char.ht);
530         wr_s16b(previous_char.wt);
531         wr_s16b(previous_char.sc);
532         wr_s32b(previous_char.au);
533
534         for (i = 0; i < 6; i++) wr_s16b(previous_char.stat_max[i]);
535         for (i = 0; i < 6; i++) wr_s16b(previous_char.stat_max_max[i]);
536
537         for (i = 0; i < PY_MAX_LEVEL; i++) wr_s16b(previous_char.player_hp[i]);
538
539         wr_s16b(previous_char.chaos_patron);
540
541         for (i = 0; i < 8; i++) wr_s16b(previous_char.vir_types[i]);
542
543         for (i = 0; i < 4; i++) wr_string(previous_char.history[i]);
544
545         /* UNUSED : Was number of random quests */
546         wr_byte(0);
547
548         /* No quick start after using debug mode or cheat options */
549         if (p_ptr->noscore) previous_char.quick_ok = FALSE;
550
551         wr_byte((byte)previous_char.quick_ok);
552 }
553
554 /*
555  * Write some "extra" info
556  */
557 static void wr_extra(void)
558 {
559         int i,j;
560         byte tmp8u;
561
562         wr_string(player_name);
563
564         wr_string(p_ptr->died_from);
565
566         wr_string(p_ptr->last_message ? p_ptr->last_message : "");
567
568         save_quick_start();
569
570         for (i = 0; i < 4; i++)
571         {
572                 wr_string(p_ptr->history[i]);
573         }
574
575         /* Race/Class/Gender/Spells */
576         wr_byte(p_ptr->prace);
577         wr_byte(p_ptr->pclass);
578         wr_byte(p_ptr->pseikaku);
579         wr_byte(p_ptr->psex);
580         wr_byte(p_ptr->realm1);
581         wr_byte(p_ptr->realm2);
582         wr_byte(0);     /* oops */
583
584         wr_byte(p_ptr->hitdie);
585         wr_u16b(p_ptr->expfact);
586
587         wr_s16b(p_ptr->age);
588         wr_s16b(p_ptr->ht);
589         wr_s16b(p_ptr->wt);
590
591         /* Dump the stats (maximum and current) */
592         for (i = 0; i < 6; ++i) wr_s16b(p_ptr->stat_max[i]);
593         for (i = 0; i < 6; ++i) wr_s16b(p_ptr->stat_max_max[i]);
594         for (i = 0; i < 6; ++i) wr_s16b(p_ptr->stat_cur[i]);
595
596         /* Ignore the transient stats */
597         for (i = 0; i < 12; ++i) wr_s16b(0);
598
599         wr_u32b(p_ptr->au);
600
601         wr_u32b(p_ptr->max_exp);
602         wr_u32b(p_ptr->max_max_exp);
603         wr_u32b(p_ptr->exp);
604         wr_u32b(p_ptr->exp_frac);
605         wr_s16b(p_ptr->lev);
606
607         for (i = 0; i < 64; i++) wr_s16b(p_ptr->spell_exp[i]);
608         for (i = 0; i < 5; i++) for (j = 0; j < 64; j++) wr_s16b(p_ptr->weapon_exp[i][j]);
609         for (i = 0; i < 10; i++) wr_s16b(p_ptr->skill_exp[i]);
610         for (i = 0; i < 108; i++) wr_s32b(p_ptr->magic_num1[i]);
611         for (i = 0; i < 108; i++) wr_byte(p_ptr->magic_num2[i]);
612
613         wr_byte(p_ptr->start_race);
614         wr_s32b(p_ptr->old_race1);
615         wr_s32b(p_ptr->old_race2);
616         wr_s16b(p_ptr->old_realm);
617
618         for (i = 0; i < MAX_MANE; i++)
619         {
620                 wr_s16b(p_ptr->mane_spell[i]);
621                 wr_s16b(p_ptr->mane_dam[i]);
622         }
623         wr_s16b(p_ptr->mane_num);
624
625         for (i = 0; i < MAX_KUBI; i++)
626         {
627                 wr_s16b(kubi_r_idx[i]);
628         }
629
630         for (i = 0; i < 4; i++)
631         {
632                 wr_s16b(battle_mon[i]);
633                 wr_u32b(mon_odds[i]);
634         }
635
636         wr_s16b(p_ptr->town_num); /* -KMW- */
637
638         /* Write arena and rewards information -KMW- */
639         wr_s16b(p_ptr->arena_number);
640         wr_s16b(p_ptr->inside_arena);
641         wr_s16b(p_ptr->inside_quest);
642         wr_s16b(p_ptr->inside_battle);
643         wr_byte(p_ptr->exit_bldg);
644         wr_byte(0); /* Unused */
645
646         wr_s16b(p_ptr->oldpx);
647         wr_s16b(p_ptr->oldpy);
648
649         /* Was number of p_ptr->rewards[] */
650         wr_s16b(0);
651
652         wr_s32b(p_ptr->mhp);
653         wr_s32b(p_ptr->chp);
654         wr_u32b(p_ptr->chp_frac);
655
656         wr_s32b(p_ptr->msp);
657         wr_s32b(p_ptr->csp);
658         wr_u32b(p_ptr->csp_frac);
659
660         /* Max Player and Dungeon Levels */
661         wr_s16b(p_ptr->max_plv);
662         tmp8u = (byte)max_d_idx;
663         wr_byte(tmp8u);
664         for (i = 0; i < tmp8u; i++)
665                 wr_s16b(max_dlv[i]);
666
667         /* More info */
668         wr_s16b(0);     /* oops */
669         wr_s16b(0);     /* oops */
670         wr_s16b(0);     /* oops */
671         wr_s16b(0);     /* oops */
672         wr_s16b(p_ptr->sc);
673         wr_s16b(p_ptr->concent);
674
675         wr_s16b(0);             /* old "rest" */
676         wr_s16b(p_ptr->blind);
677         wr_s16b(p_ptr->paralyzed);
678         wr_s16b(p_ptr->confused);
679         wr_s16b(p_ptr->food);
680         wr_s16b(0);     /* old "food_digested" */
681         wr_s16b(0);     /* old "protection" */
682         wr_s16b(p_ptr->energy_need);
683         wr_s16b(p_ptr->enchant_energy_need);
684         wr_s16b(p_ptr->fast);
685         wr_s16b(p_ptr->slow);
686         wr_s16b(p_ptr->afraid);
687         wr_s16b(p_ptr->cut);
688         wr_s16b(p_ptr->stun);
689         wr_s16b(p_ptr->poisoned);
690         wr_s16b(p_ptr->image);
691         wr_s16b(p_ptr->protevil);
692         wr_s16b(p_ptr->invuln);
693         wr_s16b(p_ptr->ult_res);
694         wr_s16b(p_ptr->hero);
695         wr_s16b(p_ptr->shero);
696         wr_s16b(p_ptr->shield);
697         wr_s16b(p_ptr->blessed);
698         wr_s16b(p_ptr->tim_invis);
699         wr_s16b(p_ptr->word_recall);
700         wr_s16b(p_ptr->recall_dungeon);
701         wr_s16b(p_ptr->alter_reality);
702         wr_s16b(p_ptr->see_infra);
703         wr_s16b(p_ptr->tim_infra);
704         wr_s16b(p_ptr->oppose_fire);
705         wr_s16b(p_ptr->oppose_cold);
706         wr_s16b(p_ptr->oppose_acid);
707         wr_s16b(p_ptr->oppose_elec);
708         wr_s16b(p_ptr->oppose_pois);
709         wr_s16b(p_ptr->tsuyoshi);
710         wr_s16b(p_ptr->tim_esp);
711         wr_s16b(p_ptr->wraith_form);
712         wr_s16b(p_ptr->resist_magic);
713         wr_s16b(p_ptr->tim_regen);
714         wr_s16b(p_ptr->kabenuke);
715         wr_s16b(p_ptr->tim_stealth);
716         wr_s16b(p_ptr->tim_levitation);
717         wr_s16b(p_ptr->tim_sh_touki);
718         wr_s16b(p_ptr->lightspeed);
719         wr_s16b(p_ptr->tsubureru);
720         wr_s16b(p_ptr->magicdef);
721         wr_s16b(p_ptr->tim_res_nether);
722         wr_s16b(p_ptr->tim_res_time);
723         wr_byte(p_ptr->mimic_form);
724         wr_s16b(p_ptr->tim_mimic);
725         wr_s16b(p_ptr->tim_sh_fire);
726         wr_s16b(p_ptr->tim_sh_holy);
727         wr_s16b(p_ptr->tim_eyeeye);
728
729         /* by henkma */
730         wr_s16b(p_ptr->tim_reflect);
731         wr_s16b(p_ptr->multishadow);
732         wr_s16b(p_ptr->dustrobe);
733
734         wr_s16b(p_ptr->chaos_patron);
735         wr_u32b(p_ptr->muta1);
736         wr_u32b(p_ptr->muta2);
737         wr_u32b(p_ptr->muta3);
738
739         for (i = 0; i<8; i++)
740                 wr_s16b(p_ptr->virtues[i]);
741         for (i = 0; i<8; i++)
742                 wr_s16b(p_ptr->vir_types[i]);
743
744         wr_s16b(p_ptr->ele_attack);
745         wr_u32b(p_ptr->special_attack);
746         wr_s16b(p_ptr->ele_immune);
747         wr_u32b(p_ptr->special_defense);
748         wr_byte(p_ptr->knowledge);
749         wr_byte(p_ptr->autopick_autoregister);
750         wr_byte(0);     /* oops */
751         wr_byte(p_ptr->action);
752         wr_byte(0);
753         wr_byte(preserve_mode);
754         wr_byte(p_ptr->wait_report_score);
755
756         /* Future use */
757         for (i = 0; i < 12; i++) wr_u32b(0L);
758
759         /* Ignore some flags */
760         wr_u32b(0L);    /* oops */
761         wr_u32b(0L);    /* oops */
762         wr_u32b(0L);    /* oops */
763
764
765         /* Write the "object seeds" */
766         wr_u32b(seed_flavor);
767         wr_u32b(seed_town);
768
769
770         /* Special stuff */
771         wr_u16b(p_ptr->panic_save);
772         wr_u16b(p_ptr->total_winner);
773         wr_u16b(p_ptr->noscore);
774
775
776         /* Write death */
777         wr_byte(p_ptr->is_dead);
778
779         /* Write feeling */
780         wr_byte(p_ptr->feeling);
781
782         /* Turn when level began */
783         wr_s32b(old_turn);
784
785         /* Turn of last "feeling" */
786         wr_s32b(p_ptr->feeling_turn);
787
788         /* Current turn */
789         wr_s32b(turn);
790
791         wr_s32b(dungeon_turn);
792
793         wr_s32b(old_battle);
794
795         wr_s16b(today_mon);
796         wr_s16b(p_ptr->today_mon);
797         wr_s16b(p_ptr->riding);
798
799         /* Current floor_id */
800         wr_s16b(p_ptr->floor_id);
801
802         /* Save temporary preserved pets (obsolated) */
803         wr_s16b(0);
804
805         wr_u32b(playtime);
806
807         wr_s32b(p_ptr->visit);
808
809         wr_u32b(p_ptr->count);
810 }
811
812
813
814 /*
815  * hook function to sort monsters by level
816  */
817 static bool ang_sort_comp_cave_temp(vptr u, vptr v, int a, int b)
818 {
819         cave_template_type *who = (cave_template_type *)(u);
820
821         u16b o1 = who[a].occurrence;
822         u16b o2 = who[b].occurrence;
823
824         /* Unused */
825         (void)v;
826
827         return o2 <= o1;
828 }
829
830
831 /*
832  * Sorting hook -- Swap function
833  */
834 static void ang_sort_swap_cave_temp(vptr u, vptr v, int a, int b)
835 {
836         cave_template_type *who = (cave_template_type *)(u);
837
838         cave_template_type holder;
839
840         /* Unused */
841         (void)v;
842
843         /* Swap */
844         holder = who[a];
845         who[a] = who[b];
846         who[b] = holder;
847 }
848
849
850 /*
851  * Actually write a saved floor data
852  * using effectively compressed format.
853  */
854 static void wr_saved_floor(saved_floor_type *sf_ptr)
855 {
856         cave_template_type *template;
857         u16b max_num_temp;
858         u16b num_temp = 0;
859         int dummy_why;
860
861         int i, y, x;
862
863         u16b tmp16u;
864
865         byte count;
866         u16b prev_u16b;
867
868
869         /*** Basic info ***/
870
871         /* Dungeon floor specific info follows */
872
873         if (!sf_ptr)
874         {
875                 /*** Not a saved floor ***/
876
877                 wr_s16b(dun_level);
878         }
879         else
880         {
881                 /*** The saved floor ***/
882
883                 wr_s16b(sf_ptr->floor_id);
884                 wr_byte(sf_ptr->savefile_id);
885                 wr_s16b(sf_ptr->dun_level);
886                 wr_s32b(sf_ptr->last_visit);
887                 wr_u32b(sf_ptr->visit_mark);
888                 wr_s16b(sf_ptr->upper_floor_id);
889                 wr_s16b(sf_ptr->lower_floor_id);
890         }
891
892         wr_u16b(base_level);
893         wr_u16b(num_repro);
894         wr_u16b((u16b)py);
895         wr_u16b((u16b)px);
896         wr_u16b(cur_hgt);
897         wr_u16b(cur_wid);
898         wr_byte(p_ptr->feeling);
899
900
901
902         /*********** Make template for cave_type **********/
903
904         /*
905          * Usually number of templates are fewer than 255.  Even if
906          * more than 254 are exist, the occurrence of each template
907          * with larger ID is very small when we sort templates by
908          * occurrence.  So we will use two (or more) bytes for
909          * templete ID larger than 254.
910          *
911          * Ex: 256 will be "0xff" "0x01".
912          *     515 will be "0xff" "0xff" "0x03"
913          */
914
915         /* Fake max number */
916         max_num_temp = 255;
917
918         /* Allocate the "template" array */
919         C_MAKE(template, max_num_temp, cave_template_type);
920
921         /* Extract template array */
922         for (y = 0; y < cur_hgt; y++)
923         {
924                 for (x = 0; x < cur_wid; x++)
925                 {
926                         cave_type *c_ptr = &cave[y][x];
927
928                         for (i = 0; i < num_temp; i++)
929                         {
930                                 if (template[i].info == c_ptr->info &&
931                                     template[i].feat == c_ptr->feat &&
932                                     template[i].mimic == c_ptr->mimic &&
933                                     template[i].special == c_ptr->special)
934                                 {
935                                         /* Same terrain is exist */
936                                         template[i].occurrence++;
937                                         break;
938                                 }
939                         }
940
941                         /* Are there same one? */
942                         if (i < num_temp) continue;
943
944                         /* If the max_num_temp is too small, increase it. */
945                         if (num_temp >= max_num_temp)
946                         {
947                                 cave_template_type *old_template = template;
948
949                                 /* Re-allocate the "template" array */
950                                 C_MAKE(template, max_num_temp + 255, cave_template_type);
951                                 C_COPY(template, old_template, max_num_temp, cave_template_type);
952                                 C_FREE(old_template, max_num_temp, cave_template_type);
953                                 max_num_temp += 255;
954                         }
955
956                         /* Add new template */
957                         template[num_temp].info = c_ptr->info;
958                         template[num_temp].feat = c_ptr->feat;
959                         template[num_temp].mimic = c_ptr->mimic;
960                         template[num_temp].special = c_ptr->special;
961                         template[num_temp].occurrence = 1;
962
963                         /* Increase number of template */
964                         num_temp++;
965                 }
966         }
967
968         /* Select the sort method */
969         ang_sort_comp = ang_sort_comp_cave_temp;
970         ang_sort_swap = ang_sort_swap_cave_temp;
971
972         /* Sort by occurrence */
973         ang_sort(template, &dummy_why, num_temp);
974
975
976         /*** Dump templates ***/
977
978         /* Total templates */
979         wr_u16b(num_temp);
980
981         /* Dump the templates */
982         for (i = 0; i < num_temp; i++)
983         {
984                 cave_template_type *ct_ptr = &template[i];
985
986                 /* Dump it */
987                 wr_u16b(ct_ptr->info);
988                 wr_s16b(ct_ptr->feat);
989                 wr_s16b(ct_ptr->mimic);
990                 wr_s16b(ct_ptr->special);
991         }
992
993
994
995         /*** "Run-Length-Encoding" of cave ***/
996
997         /* Note that this will induce two wasted bytes */
998         count = 0;
999         prev_u16b = 0;
1000
1001         /* Dump the cave */
1002         for (y = 0; y < cur_hgt; y++)
1003         {
1004                 for (x = 0; x < cur_wid; x++)
1005                 {
1006                         cave_type *c_ptr = &cave[y][x];
1007
1008                         for (i = 0; i < num_temp; i++)
1009                         {
1010                                 if (template[i].info == c_ptr->info &&
1011                                     template[i].feat == c_ptr->feat &&
1012                                     template[i].mimic == c_ptr->mimic &&
1013                                     template[i].special == c_ptr->special)
1014                                         break;
1015                         }
1016
1017                         /* Extract an ID */
1018                         tmp16u = i;
1019
1020                         /* If the run is broken, or too full, flush it */
1021                         if ((tmp16u != prev_u16b) || (count == MAX_UCHAR))
1022                         {
1023                                 wr_byte((byte)count);
1024
1025                                 while (prev_u16b >= MAX_UCHAR)
1026                                 {
1027                                         /* Mark as actual data is larger than 254 */
1028                                         wr_byte(MAX_UCHAR);
1029                                         prev_u16b -= MAX_UCHAR;
1030                                 }
1031
1032                                 wr_byte((byte)prev_u16b);
1033                                 prev_u16b = tmp16u;
1034                                 count = 1;
1035                         }
1036
1037                         /* Continue the run */
1038                         else
1039                         {
1040                                 count++;
1041                         }
1042                 }
1043         }
1044
1045         /* Flush the data (if any) */
1046         if (count)
1047         {
1048                 wr_byte((byte)count);
1049
1050                 while (prev_u16b >= MAX_UCHAR)
1051                 {
1052                         /* Mark as actual data is larger than 254 */
1053                         wr_byte(MAX_UCHAR);
1054                         prev_u16b -= MAX_UCHAR;
1055                 }
1056                 wr_byte((byte)prev_u16b);
1057         }
1058
1059
1060         /* Free the "template" array */
1061         C_FREE(template, max_num_temp, cave_template_type);
1062
1063
1064         /*** Dump objects ***/
1065
1066         /* Total objects */
1067         wr_u16b(o_max);
1068
1069         /* Dump the objects */
1070         for (i = 1; i < o_max; i++)
1071         {
1072                 object_type *o_ptr = &o_list[i];
1073
1074                 /* Dump it */
1075                 wr_item(o_ptr);
1076         }
1077
1078
1079         /*** Dump the monsters ***/
1080
1081         /* Total monsters */
1082         wr_u16b(m_max);
1083
1084         /* Dump the monsters */
1085         for (i = 1; i < m_max; i++)
1086         {
1087                 monster_type *m_ptr = &m_list[i];
1088
1089                 /* Dump it */
1090                 wr_monster(m_ptr);
1091         }
1092 }
1093
1094
1095 /*
1096  * Write the current dungeon (new method)
1097  */
1098 static bool wr_dungeon(void)
1099 {
1100         saved_floor_type *cur_sf_ptr;
1101         int i;
1102
1103         /* Forget the lite */
1104         forget_lite();
1105
1106         /* Forget the view */
1107         forget_view();
1108
1109         /* Forget the view */
1110         clear_mon_lite();
1111
1112         /* Update lite/view */
1113         p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
1114
1115         /* Update monsters */
1116         p_ptr->update |= (PU_MONSTERS | PU_DISTANCE | PU_FLOW);
1117
1118
1119         /*** Meta info ***/
1120
1121         /* Number of floor_id used from birth */
1122         wr_s16b(max_floor_id);
1123
1124         /* Current dungeon type */
1125         wr_byte(dungeon_type);
1126
1127
1128         /*** No saved floor (On the surface etc.) ***/
1129         if (!p_ptr->floor_id)
1130         {
1131                 /* No array elements */
1132                 wr_byte(0);
1133
1134                 /* Write the current floor data */
1135                 wr_saved_floor(NULL);
1136
1137                 /* Success */
1138                 return TRUE;
1139         }
1140
1141
1142         /*** In the dungeon ***/
1143
1144         /* Number of array elements */
1145         wr_byte(MAX_SAVED_FLOORS);
1146
1147         /* Write the saved_floors array */
1148         for (i = 0; i < MAX_SAVED_FLOORS; i++)
1149         {
1150                 saved_floor_type *sf_ptr = &saved_floors[i];
1151
1152                 wr_s16b(sf_ptr->floor_id);
1153                 wr_byte(sf_ptr->savefile_id);
1154                 wr_s16b(sf_ptr->dun_level);
1155                 wr_s32b(sf_ptr->last_visit);
1156                 wr_u32b(sf_ptr->visit_mark);
1157                 wr_s16b(sf_ptr->upper_floor_id);
1158                 wr_s16b(sf_ptr->lower_floor_id);
1159         }
1160
1161         /* Extract pointer to current floor */
1162         cur_sf_ptr = get_sf_ptr(p_ptr->floor_id);
1163
1164         /* Save current floor to temporal file */
1165         if (!save_floor(cur_sf_ptr, (SLF_SECOND))) return FALSE;
1166
1167         /* Move data in temporal files to the savefile */
1168         for (i = 0; i < MAX_SAVED_FLOORS; i++)
1169         {
1170                 saved_floor_type *sf_ptr = &saved_floors[i];
1171
1172                 /* Unused element */
1173                 if (!sf_ptr->floor_id) continue;
1174
1175                 /* Load temporal saved floor file */
1176                 if (load_floor(sf_ptr, (SLF_SECOND | SLF_NO_KILL)))
1177                 {
1178                         /* Mark success */
1179                         wr_byte(0);
1180
1181                         /* Write saved floor data to the save file */
1182                         wr_saved_floor(sf_ptr);
1183                 }
1184                 else
1185                 {
1186                         /* Mark failure */
1187                         wr_byte(1);
1188                 }
1189         }
1190
1191         /* Restore current floor */
1192         if (!load_floor(cur_sf_ptr, (SLF_SECOND))) return FALSE;
1193
1194         /* Success */
1195         return TRUE;
1196 }
1197
1198
1199
1200 /*
1201  * Actually write a save-file
1202  */
1203 static bool wr_savefile_new(void)
1204 {
1205         int        i, j;
1206
1207         u32b              now;
1208
1209         byte            tmp8u;
1210         u16b            tmp16u;
1211
1212
1213         /* Compact the objects */
1214         compact_objects(0);
1215         /* Compact the monsters */
1216         compact_monsters(0);
1217
1218         /* Guess at the current time */
1219         now = time((time_t *)0);
1220
1221
1222         /* Note the operating system */
1223         sf_system = 0L;
1224
1225         /* Note when the file was saved */
1226         sf_when = now;
1227
1228         /* Note the number of saves */
1229         sf_saves++;
1230
1231
1232         /*** Actually write the file ***/
1233
1234         /* Dump the file header */
1235         xor_byte = 0;
1236         wr_byte(FAKE_VER_MAJOR);
1237         xor_byte = 0;
1238         wr_byte(FAKE_VER_MINOR);
1239         xor_byte = 0;
1240         wr_byte(FAKE_VER_PATCH);
1241         xor_byte = 0;
1242
1243         /* Initial value of xor_byte */
1244         tmp8u = (byte)randint0(256);
1245         wr_byte(tmp8u);
1246
1247
1248         /* Reset the checksum */
1249         v_stamp = 0L;
1250         x_stamp = 0L;
1251
1252         /* Write the savefile version for Hengband 1.1.1 and later */
1253         wr_byte(H_VER_EXTRA);
1254         wr_byte(H_VER_PATCH);
1255         wr_byte(H_VER_MINOR);
1256         wr_byte(H_VER_MAJOR);
1257
1258         /* Operating system */
1259         wr_u32b(sf_system);
1260
1261
1262         /* Time file last saved */
1263         wr_u32b(sf_when);
1264
1265         /* Number of past lives */
1266         wr_u16b(sf_lives);
1267
1268         /* Number of times saved */
1269         wr_u16b(sf_saves);
1270
1271
1272         /* Space */
1273         wr_u32b(0L);
1274         wr_u16b(0);
1275         wr_byte(0);
1276
1277 #ifdef JP
1278 # ifdef EUC
1279         /* EUC kanji code */
1280         wr_byte(2);
1281 # endif
1282 # ifdef SJIS
1283         /* SJIS kanji code */
1284         wr_byte(3);
1285 # endif
1286 #else
1287         /* ASCII */
1288         wr_byte(1);
1289 #endif
1290
1291         /* Write the RNG state */
1292         wr_randomizer();
1293
1294
1295         /* Write the boolean "options" */
1296         wr_options();
1297
1298
1299         /* Dump the number of "messages" */
1300         tmp16u = message_num();
1301         if (compress_savefile && (tmp16u > 40)) tmp16u = 40;
1302         wr_u16b(tmp16u);
1303
1304         /* Dump the messages (oldest first!) */
1305         for (i = tmp16u - 1; i >= 0; i--)
1306         {
1307                 wr_string(message_str((s16b)i));
1308         }
1309
1310
1311         /* Dump the monster lore */
1312         tmp16u = max_r_idx;
1313         wr_u16b(tmp16u);
1314         for (i = 0; i < tmp16u; i++) wr_lore(i);
1315
1316
1317         /* Dump the object memory */
1318         tmp16u = max_k_idx;
1319         wr_u16b(tmp16u);
1320         for (i = 0; i < tmp16u; i++) wr_xtra(i);
1321
1322         /* Dump the towns */
1323         tmp16u = max_towns;
1324         wr_u16b(tmp16u);
1325
1326         /* Dump the quests */
1327         tmp16u = max_quests;
1328         wr_u16b(tmp16u);
1329
1330         /* Dump the quests */
1331         tmp8u = MAX_RANDOM_QUEST-MIN_RANDOM_QUEST;
1332         wr_byte(tmp8u);
1333
1334         for (i = 0; i < max_quests; i++)
1335         {
1336                 /* Save status for every quest */
1337                 wr_s16b(quest[i].status);
1338
1339                 /* And the dungeon level too */
1340                 /* (prevents problems with multi-level quests) */
1341                 wr_s16b(quest[i].level);
1342
1343                 wr_byte(quest[i].complev);
1344
1345                 /* Save quest status if quest is running */
1346                 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_COMPLETED || !is_fixed_quest_idx(i))
1347                 {
1348                         wr_s16b(quest[i].cur_num);
1349                         wr_s16b(quest[i].max_num);
1350                         wr_s16b(quest[i].type);
1351                         wr_s16b(quest[i].r_idx);
1352                         wr_s16b(quest[i].k_idx);
1353                         wr_byte(quest[i].flags);
1354                         wr_byte(quest[i].dungeon);
1355                 }
1356         }
1357
1358         /* Dump the position in the wilderness */
1359         wr_s32b(p_ptr->wilderness_x);
1360         wr_s32b(p_ptr->wilderness_y);
1361
1362         wr_byte(p_ptr->wild_mode);
1363         wr_byte(ambush_flag);
1364
1365         wr_s32b(max_wild_x);
1366         wr_s32b(max_wild_y);
1367
1368         /* Dump the wilderness seeds */
1369         for (i = 0; i < max_wild_x; i++)
1370         {
1371                 for (j = 0; j < max_wild_y; j++)
1372                 {
1373                         wr_u32b(wilderness[j][i].seed);
1374                 }
1375         }
1376
1377         /* Hack -- Dump the artifacts */
1378         tmp16u = max_a_idx;
1379         wr_u16b(tmp16u);
1380         for (i = 0; i < tmp16u; i++)
1381         {
1382                 artifact_type *a_ptr = &a_info[i];
1383                 wr_byte(a_ptr->cur_num);
1384                 wr_s16b(a_ptr->floor_id);
1385         }
1386
1387
1388
1389         /* Write the "extra" information */
1390         wr_extra();
1391
1392         /* Dump the "player hp" entries */
1393         tmp16u = PY_MAX_LEVEL;
1394         wr_u16b(tmp16u);
1395         for (i = 0; i < tmp16u; i++)
1396         {
1397                 wr_s16b(p_ptr->player_hp[i]);
1398         }
1399
1400
1401         /* Write spell data */
1402         wr_u32b(p_ptr->spell_learned1);
1403         wr_u32b(p_ptr->spell_learned2);
1404         wr_u32b(p_ptr->spell_worked1);
1405         wr_u32b(p_ptr->spell_worked2);
1406         wr_u32b(p_ptr->spell_forgotten1);
1407         wr_u32b(p_ptr->spell_forgotten2);
1408
1409         wr_s16b(p_ptr->learned_spells);
1410         wr_s16b(p_ptr->add_spells);
1411
1412         /* Dump the ordered spells */
1413         for (i = 0; i < 64; i++)
1414         {
1415                 wr_byte(p_ptr->spell_order[i]);
1416         }
1417
1418
1419         /* Write the inventory */
1420         for (i = 0; i < INVEN_TOTAL; i++)
1421         {
1422                 object_type *o_ptr = &inventory[i];
1423
1424                 /* Skip non-objects */
1425                 if (!o_ptr->k_idx) continue;
1426
1427                 /* Dump index */
1428                 wr_u16b((u16b)i);
1429
1430                 /* Dump object */
1431                 wr_item(o_ptr);
1432         }
1433
1434         /* Add a sentinel */
1435         wr_u16b(0xFFFF);
1436
1437         /* Note the towns */
1438         tmp16u = max_towns;
1439         wr_u16b(tmp16u);
1440
1441         /* Note the stores */
1442         tmp16u = MAX_STORES;
1443         wr_u16b(tmp16u);
1444
1445         /* Dump the stores of all towns */
1446         for (i = 1; i < max_towns; i++)
1447         {
1448                 for (j = 0; j < MAX_STORES; j++)
1449                 {
1450                         wr_store(&town[i].store[j]);
1451                 }
1452         }
1453
1454         /* Write the pet command settings */
1455         wr_s16b(p_ptr->pet_follow_distance);
1456         wr_s16b(p_ptr->pet_extra_flags);
1457
1458         /* Write screen dump for sending score */
1459         if (screen_dump && (p_ptr->wait_report_score || !p_ptr->is_dead))
1460         {
1461                 wr_string(screen_dump);
1462         }
1463         else
1464         {
1465                 wr_string("");
1466         }
1467
1468         /* Player is not dead, write the dungeon */
1469         if (!p_ptr->is_dead)
1470         {
1471                 /* Dump the dungeon */
1472                 if (!wr_dungeon()) return FALSE;
1473
1474                 /* Dump the ghost */
1475                 wr_ghost();
1476
1477                 /* No scripts */
1478                 wr_s32b(0);
1479         }
1480
1481
1482         /* Write the "value check-sum" */
1483         wr_u32b(v_stamp);
1484
1485         /* Write the "encoded checksum" */
1486         wr_u32b(x_stamp);
1487
1488
1489         /* Error in save */
1490         if (ferror(fff) || (fflush(fff) == EOF)) return FALSE;
1491
1492         /* Successful save */
1493         return TRUE;
1494 }
1495
1496
1497 /*
1498  * Medium level player saver
1499  *
1500  * XXX XXX XXX Angband 2.8.0 will use "fd" instead of "fff" if possible
1501  */
1502 static bool save_player_aux(char *name)
1503 {
1504         bool    ok = FALSE;
1505
1506         int             fd = -1;
1507
1508         int             mode = 0644;
1509
1510
1511         /* No file yet */
1512         fff = NULL;
1513
1514
1515         /* File type is "SAVE" */
1516         FILE_TYPE(FILE_TYPE_SAVE);
1517
1518
1519         /* Grab permissions */
1520         safe_setuid_grab();
1521
1522         /* Create the savefile */
1523         fd = fd_make(name, mode);
1524
1525         /* Drop permissions */
1526         safe_setuid_drop();
1527
1528         /* File is okay */
1529         if (fd >= 0)
1530         {
1531                 /* Close the "fd" */
1532                 (void)fd_close(fd);
1533
1534                 /* Grab permissions */
1535                 safe_setuid_grab();
1536
1537                 /* Open the savefile */
1538                 fff = my_fopen(name, "wb");
1539
1540                 /* Drop permissions */
1541                 safe_setuid_drop();
1542
1543                 /* Successful open */
1544                 if (fff)
1545                 {
1546                         /* Write the savefile */
1547                         if (wr_savefile_new()) ok = TRUE;
1548
1549                         /* Attempt to close it */
1550                         if (my_fclose(fff)) ok = FALSE;
1551                 }
1552
1553                 /* Grab permissions */
1554                 safe_setuid_grab();
1555
1556                 /* Remove "broken" files */
1557                 if (!ok) (void)fd_kill(name);
1558
1559                 /* Drop permissions */
1560                 safe_setuid_drop();
1561         }
1562
1563
1564         /* Failure */
1565         if (!ok) return (FALSE);
1566
1567         counts_write(0, playtime);
1568
1569         /* Successful save */
1570         character_saved = TRUE;
1571
1572         /* Success */
1573         return (TRUE);
1574 }
1575
1576
1577
1578 /*
1579  * Attempt to save the player in a savefile
1580  */
1581 bool save_player(void)
1582 {
1583         int             result = FALSE;
1584
1585         char    safe[1024];
1586
1587
1588 #ifdef SET_UID
1589
1590 # ifdef SECURE
1591
1592         /* Get "games" permissions */
1593         beGames();
1594
1595 # endif
1596
1597 #endif
1598
1599
1600         /* New savefile */
1601         strcpy(safe, savefile);
1602         strcat(safe, ".new");
1603
1604 #ifdef VM
1605         /* Hack -- support "flat directory" usage on VM/ESA */
1606         strcpy(safe, savefile);
1607         strcat(safe, "n");
1608 #endif /* VM */
1609
1610         /* Grab permissions */
1611         safe_setuid_grab();
1612
1613         /* Remove it */
1614         fd_kill(safe);
1615
1616         /* Drop permissions */
1617         safe_setuid_drop();
1618
1619         update_playtime();
1620
1621         /* Attempt to save the player */
1622         if (save_player_aux(safe))
1623         {
1624                 char temp[1024];
1625
1626                 /* Old savefile */
1627                 strcpy(temp, savefile);
1628                 strcat(temp, ".old");
1629
1630 #ifdef VM
1631                 /* Hack -- support "flat directory" usage on VM/ESA */
1632                 strcpy(temp, savefile);
1633                 strcat(temp, "o");
1634 #endif /* VM */
1635
1636                 /* Grab permissions */
1637                 safe_setuid_grab();
1638
1639                 /* Remove it */
1640                 fd_kill(temp);
1641
1642                 /* Preserve old savefile */
1643                 fd_move(savefile, temp);
1644
1645                 /* Activate new savefile */
1646                 fd_move(safe, savefile);
1647
1648                 /* Remove preserved savefile */
1649                 fd_kill(temp);
1650
1651                 /* Drop permissions */
1652                 safe_setuid_drop();
1653
1654                 /* Hack -- Pretend the character was loaded */
1655                 character_loaded = TRUE;
1656
1657 #ifdef VERIFY_SAVEFILE
1658
1659                 /* Lock on savefile */
1660                 strcpy(temp, savefile);
1661                 strcat(temp, ".lok");
1662
1663                 /* Grab permissions */
1664                 safe_setuid_grab();
1665
1666                 /* Remove lock file */
1667                 fd_kill(temp);
1668
1669                 /* Drop permissions */
1670                 safe_setuid_drop();
1671
1672 #endif
1673
1674                 /* Success */
1675                 result = TRUE;
1676         }
1677
1678
1679 #ifdef SET_UID
1680
1681 # ifdef SECURE
1682
1683         /* Drop "games" permissions */
1684         bePlayer();
1685
1686 # endif
1687
1688 #endif
1689
1690         /* Return the result */
1691         return (result);
1692 }
1693
1694
1695
1696 /*
1697  * Attempt to Load a "savefile"
1698  *
1699  * Version 2.7.0 introduced a slightly different "savefile" format from
1700  * older versions, requiring a completely different parsing method.
1701  *
1702  * Note that savefiles from 2.7.0 - 2.7.2 are completely obsolete.
1703  *
1704  * Pre-2.8.0 savefiles lose some data, see "load2.c" for info.
1705  *
1706  * Pre-2.7.0 savefiles lose a lot of things, see "load1.c" for info.
1707  *
1708  * On multi-user systems, you may only "read" a savefile if you will be
1709  * allowed to "write" it later, this prevents painful situations in which
1710  * the player loads a savefile belonging to someone else, and then is not
1711  * allowed to save his game when he quits.
1712  *
1713  * We return "TRUE" if the savefile was usable, and we set the global
1714  * flag "character_loaded" if a real, living, character was loaded.
1715  *
1716  * Note that we always try to load the "current" savefile, even if
1717  * there is no such file, so we must check for "empty" savefile names.
1718  */
1719 bool load_player(void)
1720 {
1721         int             fd = -1;
1722
1723         errr    err = 0;
1724
1725         byte    vvv[4];
1726
1727 #ifdef VERIFY_TIMESTAMP
1728         struct stat     statbuf;
1729 #endif
1730
1731         cptr    what = "generic";
1732
1733
1734         /* Paranoia */
1735         turn = 0;
1736
1737         /* Paranoia */
1738         p_ptr->is_dead = FALSE;
1739
1740
1741         /* Allow empty savefile name */
1742         if (!savefile[0]) return (TRUE);
1743
1744
1745 #if !defined(MACINTOSH) && !defined(WINDOWS) && !defined(VM)
1746
1747         /* XXX XXX XXX Fix this */
1748
1749         /* Verify the existance of the savefile */
1750         if (access(savefile, 0) < 0)
1751         {
1752                 /* Give a message */
1753 #ifdef JP
1754                 msg_print("¥»¡¼¥Ö¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó¡£");
1755 #else
1756                 msg_print("Savefile does not exist.");
1757 #endif
1758
1759                 msg_print(NULL);
1760
1761                 /* Allow this */
1762                 return (TRUE);
1763         }
1764
1765 #endif
1766
1767
1768 #ifdef VERIFY_SAVEFILE
1769
1770         /* Verify savefile usage */
1771         if (!err)
1772         {
1773                 FILE *fkk;
1774
1775                 char temp[1024];
1776
1777                 /* Extract name of lock file */
1778                 strcpy(temp, savefile);
1779                 strcat(temp, ".lok");
1780
1781                 /* Check for lock */
1782                 fkk = my_fopen(temp, "r");
1783
1784                 /* Oops, lock exists */
1785                 if (fkk)
1786                 {
1787                         /* Close the file */
1788                         my_fclose(fkk);
1789
1790                         /* Message */
1791 #ifdef JP
1792                         msg_print("¥»¡¼¥Ö¥Õ¥¡¥¤¥ë¤Ï¸½ºß»ÈÍÑÃæ¤Ç¤¹¡£");
1793 #else
1794                         msg_print("Savefile is currently in use.");
1795 #endif
1796
1797                         msg_print(NULL);
1798
1799                         /* Oops */
1800                         return (FALSE);
1801                 }
1802
1803                 /* Create a lock file */
1804                 fkk = my_fopen(temp, "w");
1805
1806                 /* Dump a line of info */
1807                 fprintf(fkk, "Lock file for savefile '%s'\n", savefile);
1808
1809                 /* Close the lock file */
1810                 my_fclose(fkk);
1811         }
1812
1813 #endif
1814
1815
1816         /* Okay */
1817         if (!err)
1818         {
1819                 /* Open the savefile */
1820                 fd = fd_open(savefile, O_RDONLY);
1821
1822                 /* No file */
1823                 if (fd < 0) err = -1;
1824
1825                 /* Message (below) */
1826 #ifdef JP
1827                 if (err) what = "¥»¡¼¥Ö¥Õ¥¡¥¤¥ë¤ò³«¤±¤Þ¤»¤ó¡£";
1828 #else
1829                 if (err) what = "Cannot open savefile";
1830 #endif
1831
1832         }
1833
1834         /* Process file */
1835         if (!err)
1836         {
1837
1838 #ifdef VERIFY_TIMESTAMP
1839                 /* Get the timestamp */
1840                 (void)fstat(fd, &statbuf);
1841 #endif
1842
1843                 /* Read the first four bytes */
1844                 if (fd_read(fd, (char*)(vvv), 4)) err = -1;
1845
1846                 /* What */
1847 #ifdef JP
1848                 if (err) what = "¥»¡¼¥Ö¥Õ¥¡¥¤¥ë¤òÆɤá¤Þ¤»¤ó¡£";
1849 #else
1850                 if (err) what = "Cannot read savefile";
1851 #endif
1852
1853
1854                 /* Close the file */
1855                 (void)fd_close(fd);
1856         }
1857
1858         /* Process file */
1859         if (!err)
1860         {
1861
1862                 /* Extract version */
1863                 z_major = vvv[0];
1864                 z_minor = vvv[1];
1865                 z_patch = vvv[2];
1866                 sf_extra = vvv[3];
1867
1868
1869                 /* Clear screen */
1870                 Term_clear();
1871
1872                 /* Attempt to load */
1873                 err = rd_savefile_new();
1874
1875                 /* Message (below) */
1876 #ifdef JP
1877                 if (err) what = "¥»¡¼¥Ö¥Õ¥¡¥¤¥ë¤ò²òÀϽÐÍè¤Þ¤»¤ó¡£";
1878 #else
1879                 if (err) what = "Cannot parse savefile";
1880 #endif
1881
1882         }
1883
1884         /* Paranoia */
1885         if (!err)
1886         {
1887                 /* Invalid turn */
1888                 if (!turn) err = -1;
1889
1890                 /* Message (below) */
1891 #ifdef JP
1892                 if (err) what = "¥»¡¼¥Ö¥Õ¥¡¥¤¥ë¤¬²õ¤ì¤Æ¤¤¤Þ¤¹";
1893 #else
1894                 if (err) what = "Broken savefile";
1895 #endif
1896
1897         }
1898
1899 #ifdef VERIFY_TIMESTAMP
1900         /* Verify timestamp */
1901         if (!err && !arg_wizard)
1902         {
1903                 /* Hack -- Verify the timestamp */
1904                 if (sf_when > (statbuf.st_ctime + 100) ||
1905                     sf_when < (statbuf.st_ctime - 100))
1906                 {
1907                         /* Message */
1908 #ifdef JP
1909                         what = "̵¸ú¤Ê¥¿¥¤¥à¡¦¥¹¥¿¥ó¥×¤Ç¤¹";
1910 #else
1911                         what = "Invalid timestamp";
1912 #endif
1913
1914
1915                         /* Oops */
1916                         err = -1;
1917                 }
1918         }
1919 #endif
1920
1921
1922         /* Okay */
1923         if (!err)
1924         {
1925                 /* Give a conversion warning */
1926                 if ((FAKE_VER_MAJOR != z_major) ||
1927                     (FAKE_VER_MINOR != z_minor) ||
1928                     (FAKE_VER_PATCH != z_patch))
1929                 {
1930                         if (z_major == 2 && z_minor == 0 && z_patch == 6)
1931                         {
1932 #ifdef JP
1933                                 msg_print("¥Ð¡¼¥¸¥ç¥ó 2.0.* ÍѤΥ»¡¼¥Ö¥Õ¥¡¥¤¥ë¤òÊÑ´¹¤·¤Þ¤·¤¿¡£");
1934 #else
1935                                 msg_print("Converted a 2.0.* savefile.");
1936 #endif
1937
1938                         }
1939                         else
1940                         {
1941                                 /* Message */
1942 #ifdef JP
1943                                 msg_format("¥Ð¡¼¥¸¥ç¥ó %d.%d.%d ÍѤΥ»¡¼¥Ö¡¦¥Õ¥¡¥¤¥ë¤òÊÑ´¹¤·¤Þ¤·¤¿¡£",
1944                                     (z_major > 9) ? z_major-10 : z_major , z_minor, z_patch);
1945 #else
1946                                 msg_format("Converted a %d.%d.%d savefile.",
1947                                     (z_major > 9) ? z_major-10 : z_major , z_minor, z_patch);
1948 #endif
1949                         }
1950                         msg_print(NULL);
1951                 }
1952
1953                 /* Player is dead */
1954                 if (p_ptr->is_dead)
1955                 {
1956                         /* Cheat death */
1957                         if (arg_wizard)
1958                         {
1959                                 /* A character was loaded */
1960                                 character_loaded = TRUE;
1961
1962                                 /* Done */
1963                                 return (TRUE);
1964                         }
1965
1966                         /* Player is no longer "dead" */
1967                         p_ptr->is_dead = FALSE;
1968
1969                         /* Count lives */
1970                         sf_lives++;
1971
1972                         /* Done */
1973                         return (TRUE);
1974                 }
1975
1976                 /* A character was loaded */
1977                 character_loaded = TRUE;
1978
1979                 {
1980                         u32b tmp = counts_read(2);
1981                         if (tmp > p_ptr->count)
1982                                 p_ptr->count = tmp;
1983                         if (counts_read(0) > playtime || counts_read(1) == playtime)
1984                                 counts_write(2, ++p_ptr->count);
1985                         counts_write(1, playtime);
1986                 }
1987
1988                 /* Success */
1989                 return (TRUE);
1990         }
1991
1992
1993 #ifdef VERIFY_SAVEFILE
1994
1995         /* Verify savefile usage */
1996         if (TRUE)
1997         {
1998                 char temp[1024];
1999
2000                 /* Extract name of lock file */
2001                 strcpy(temp, savefile);
2002                 strcat(temp, ".lok");
2003
2004                 /* Remove lock */
2005                 fd_kill(temp);
2006         }
2007
2008 #endif
2009
2010
2011         /* Message */
2012 #ifdef JP
2013         msg_format("¥¨¥é¡¼(%s)¤¬¥Ð¡¼¥¸¥ç¥ó%d.%d.%d ÍÑ¥»¡¼¥Ö¥Õ¥¡¥¤¥ëÆɤ߹þÃæ¤ËȯÀ¸¡£",
2014                    what, (z_major>9) ? z_major - 10 : z_major, z_minor, z_patch);
2015 #else
2016         msg_format("Error (%s) reading %d.%d.%d savefile.",
2017                    what, (z_major>9) ? z_major - 10 : z_major, z_minor, z_patch);
2018 #endif
2019         msg_print(NULL);
2020
2021         /* Oops */
2022         return (FALSE);
2023 }
2024
2025
2026 void remove_loc(void)
2027 {
2028 #ifdef VERIFY_SAVEFILE
2029         char temp[1024];
2030 #endif /* VERIFY_SAVEFILE */
2031
2032 #ifdef SET_UID
2033 # ifdef SECURE
2034
2035         /* Get "games" permissions */
2036         beGames();
2037
2038 # endif /* SECURE */
2039 #endif /* SET_UID */
2040
2041 #ifdef VERIFY_SAVEFILE
2042
2043         /* Lock on savefile */
2044         strcpy(temp, savefile);
2045         strcat(temp, ".lok");
2046
2047         /* Remove lock file */
2048         fd_kill(temp);
2049
2050 #endif /* VERIFY_SAVEFILE */
2051
2052 #ifdef SET_UID
2053 # ifdef SECURE
2054
2055         /* Drop "games" permissions */
2056         bePlayer();
2057
2058 # endif /* SECURE */
2059 #endif /* SET_UID */
2060
2061 }
2062
2063
2064 /*
2065  * Actually write a temporal saved floor file
2066  */
2067 static bool save_floor_aux(saved_floor_type *sf_ptr)
2068 {
2069         byte tmp8u;
2070
2071         /* Compact the objects */
2072         compact_objects(0);
2073         /* Compact the monsters */
2074         compact_monsters(0);
2075
2076
2077         /*** Actually write the file ***/
2078
2079         /* Initial value of xor_byte */
2080         tmp8u = (byte)randint0(256);
2081         xor_byte = 0;
2082         wr_byte(tmp8u);
2083
2084
2085         /* Reset the checksum */
2086         v_stamp = 0L;
2087         x_stamp = 0L;
2088
2089         /* Write the sign of this process */
2090         wr_u32b(saved_floor_file_sign);
2091
2092         /* Dump the dungeon floor */
2093         wr_saved_floor(sf_ptr);
2094
2095
2096         /* Write the "value check-sum" */
2097         wr_u32b(v_stamp);
2098
2099         /* Write the "encoded checksum" */
2100         wr_u32b(x_stamp);
2101
2102
2103         /* Error in save */
2104         if (ferror(fff) || (fflush(fff) == EOF)) return FALSE;
2105
2106         /* Successful save */
2107         return TRUE;
2108 }
2109
2110
2111 /*
2112  * Attempt to save the temporally saved-floor data
2113  */
2114 bool save_floor(saved_floor_type *sf_ptr, u32b mode)
2115 {
2116         FILE *old_fff = NULL;
2117         byte old_xor_byte = 0;
2118         u32b old_v_stamp = 0;
2119         u32b old_x_stamp = 0;
2120
2121         char floor_savefile[1024];
2122         int fd = -1;
2123         bool ok = FALSE;
2124
2125         if (!(mode & SLF_SECOND))
2126         {
2127 #ifdef SET_UID
2128 # ifdef SECURE
2129                 /* Get "games" permissions */
2130                 beGames();
2131 # endif
2132 #endif
2133         }
2134
2135         /* We have one file already opened */
2136         else
2137         {
2138                 /* Backup original values */
2139                 old_fff = fff;
2140                 old_xor_byte = xor_byte;
2141                 old_v_stamp = v_stamp;
2142                 old_x_stamp = x_stamp;
2143         }
2144
2145         /* New savefile */
2146         sprintf(floor_savefile, "%s.F%02d", savefile, (int)sf_ptr->savefile_id);
2147
2148         /* Grab permissions */
2149         safe_setuid_grab();
2150
2151         /* Remove it */
2152         fd_kill(floor_savefile);
2153
2154         /* Drop permissions */
2155         safe_setuid_drop();
2156
2157
2158         /* Attempt to save the player */
2159
2160         /* No file yet */
2161         fff = NULL;
2162
2163         /* File type is "SAVE" */
2164         FILE_TYPE(FILE_TYPE_SAVE);
2165
2166         /* Grab permissions */
2167         safe_setuid_grab();
2168
2169         /* Create the savefile */
2170         fd = fd_make(floor_savefile, 0644);
2171
2172         /* Drop permissions */
2173         safe_setuid_drop();
2174
2175         /* File is okay */
2176         if (fd >= 0)
2177         {
2178                 /* Close the "fd" */
2179                 (void)fd_close(fd);
2180
2181                 /* Grab permissions */
2182                 safe_setuid_grab();
2183
2184                 /* Open the savefile */
2185                 fff = my_fopen(floor_savefile, "wb");
2186
2187                 /* Drop permissions */
2188                 safe_setuid_drop();
2189
2190                 /* Successful open */
2191                 if (fff)
2192                 {
2193                         /* Write the savefile */
2194                         if (save_floor_aux(sf_ptr)) ok = TRUE;
2195
2196                         /* Attempt to close it */
2197                         if (my_fclose(fff)) ok = FALSE;
2198                 }
2199
2200                 /* Remove "broken" files */
2201                 if (!ok)
2202                 {
2203                         /* Grab permissions */
2204                         safe_setuid_grab();
2205
2206                         (void)fd_kill(floor_savefile);
2207
2208                         /* Drop permissions */
2209                         safe_setuid_drop();
2210                 }
2211         }
2212
2213         if (!(mode & SLF_SECOND))
2214         {
2215 #ifdef SET_UID
2216 # ifdef SECURE
2217                 /* Drop "games" permissions */
2218                 bePlayer();
2219 # endif
2220 #endif
2221         }
2222
2223         /* We have one file already opened */
2224         else
2225         {
2226                 /* Restore original values */
2227                 fff = old_fff;
2228                 xor_byte = old_xor_byte;
2229                 v_stamp = old_v_stamp;
2230                 x_stamp = old_x_stamp;
2231         }
2232
2233         /* Return the result */
2234         return ok;
2235 }