OSDN Git Service

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