Ticket #10: 002-notes

File 002-notes, 20.9 KB (added by takkaria, 12 years ago)

don't include irrelevant bits

Line 
1Index: src/birth.c
2===================================================================
3--- src/birth.c (revision 635)
4+++ src/birth.c (working copy)
5@@ -1937,6 +1937,11 @@
6                player_birth_aux();
7        }
8 
9+
10+       /* Clear old messages, add new starting message */
11+       history_clear();
12+       history_add("Began the quest to destroy Morgoth.", HISTORY_PLAYER_BIRTH, 0);
13+
14        /* Note player birth in the message recall */
15        message_add(" ", MSG_GENERIC);
16        message_add("  ", MSG_GENERIC);
17Index: src/load.c
18===================================================================
19--- src/load.c  (revision 635)
20+++ src/load.c  (working copy)
21@@ -2049,6 +2049,7 @@
22        u32b n_x_check, n_v_check;
23        u32b o_x_check, o_v_check;
24 
25+       char buf[80];
26 
27        /* Mention the savefile version */
28        note(format("Loading a %d.%d.%d savefile...",
29@@ -2257,7 +2258,46 @@
30                rd_ghost();
31        }
32 
33+       /* Read in the history list if the savefile is new enough */
34+       if (!older_than(3, 0, 11))
35+       {
36+               size_t i;
37 
38+               history_clear();
39+
40+               rd_u32b(&tmp32u);
41+               for (i = 0; i < tmp32u; i++)
42+               {
43+                       s32b turn;
44+                       s16b dlev, clev;
45+                       u16b type;
46+                       byte art_name;
47+                       char text[80];
48+
49+                       rd_u16b(&type);
50+                       rd_s32b(&turn);
51+                       rd_s16b(&dlev);
52+                       rd_s16b(&clev);
53+                       rd_byte(&art_name);
54+                       rd_string(text, sizeof(text));
55+
56+                       history_add_full(type, art_name, dlev, clev, turn, text);
57+               }
58+       }
59+
60+       /*
61+        * Savefile is from an older version:
62+        * Still have to initialize the variables correctly.
63+        * Then the game should correctly log future history entries.
64+        */
65+       else
66+       {
67+               history_clear();
68+               strnfmt(buf, sizeof(buf), "Imported an Angband %d.%d.%d savefile",
69+                       sf_major, sf_minor, sf_patch);
70+               history_add(buf, HISTORY_SAVEFILE_IMPORT, 0);
71+       }
72+
73        /* Save the checksum */
74        n_v_check = v_check;
75 
76Index: src/defines.h
77===================================================================
78--- src/defines.h       (revision 635)
79+++ src/defines.h       (working copy)
80@@ -212,7 +212,19 @@
81  */
82 #define AUTOINSCRIPTIONS_MAX 216
83 
84+/* History message types */
85+#define HISTORY_PLAYER_BIRTH     0x0001        /* Player was born */
86+#define HISTORY_ARTIFACT_UNKNOWN 0x0002        /* Player found but not IDd an artifact */
87+#define HISTORY_ARTIFACT_KNOWN   0x0004        /* Player has IDed an artifact */
88+#define HISTORY_ARTIFACT_LOST    0x0008        /* Player had an artifact and lost it */
89+#define HISTORY_PLAYER_DEATH     0x0010        /* Player has been slain */
90+#define HISTORY_SLAY_UNIQUE      0x0020        /* Player has slain a unique monster */
91+#define HISTORY_USER_INPUT       0x0040        /* User-added note */
92+#define HISTORY_SAVEFILE_IMPORT  0x0080        /* Added when an older version savefile is imported */
93+#define HISTORY_GAIN_LEVEL       0x0100        /* Player gained a level */
94+#define HISTORY_GENERIC          0x0200        /* Anything else not covered here (unused) */
95 
96+
97 /*
98  * Store constants
99  *
100Index: src/Makefile.src
101===================================================================
102--- src/Makefile.src    (revision 635)
103+++ src/Makefile.src    (working copy)
104@@ -68,6 +68,7 @@
105        game-cmd.o \
106        game-event.o \
107        generate.o \
108+       history.o \
109        init1.o \
110        init2.o \
111        load.o \
112Index: src/death.c
113===================================================================
114--- src/death.c (revision 635)
115+++ src/death.c (working copy)
116@@ -373,6 +373,18 @@
117 
118 
119 /*
120+ * Menu command: view character history.
121+ */
122+static void death_history(void *unused, const char *title)
123+{
124+       (void)unused;
125+       (void)title;
126+
127+       history_display();
128+}
129+
130+
131+/*
132  * Menu structures for the death menu.
133  */
134 static menu_type death_menu;
135@@ -383,6 +395,7 @@
136        { 'f', "File dump",     death_file,     NULL },
137        { 'v', "View scores",   death_scores,   NULL },
138        { 'x', "Examine items", death_examine,  NULL },
139+       { 'h', "History",       death_history,  NULL },
140        { 'q', "Quit",          death_examine,  NULL },
141 };
142 
143@@ -421,7 +434,7 @@
144 {
145        menu_type *menu;
146        const char cmd_keys[] = { ARROW_LEFT, ARROW_RIGHT, '\0' };
147-       const region area = { 51, 2, 0, 6 };
148+       const region area = { 51, 2, 0, 7 };
149 
150        int cursor = 0;
151        ui_event_data c = EVENT_EMPTY;
152@@ -472,7 +485,7 @@
153        {
154                c = menu_select(&death_menu, &cursor, 0);
155 
156-               if (c.key == ESCAPE || cursor == 5)
157+               if (c.key == ESCAPE || cursor == 6)
158                {
159                        if (get_check("Do you want to quit? "))
160                                break;
161Index: src/externs.h
162===================================================================
163--- src/externs.h       (revision 635)
164+++ src/externs.h       (working copy)
165@@ -245,6 +245,9 @@
166 extern autoinscription *inscriptions;
167 extern u16b inscriptions_count;
168 
169+/* history.c */
170+extern history_info *history_list;
171+
172 /* squelch.c */
173 extern byte squelch_level[SQUELCH_BYTES];
174 
175@@ -341,6 +344,16 @@
176 /* generate.c */
177 extern void generate_cave(void);
178 
179+/* history.c */
180+void history_clear(void);
181+size_t history_get_num(void);
182+bool history_add_full(u16b type, byte a_idx, s16b dlev, s16b clev, s32b turn, const char *text);
183+bool history_add(const char *event, u16b type, byte a_idx);
184+bool history_add_artifact(byte a_idx, bool known);
185+void history_unmask_unknown(void);
186+bool history_lose_artifact(byte a_idx);
187+void history_display(void);
188+
189 /* init2.c */
190 extern void init_file_paths(const char *path);
191 extern void create_user_dirs(void);
192Index: src/history.c
193===================================================================
194--- src/history.c       (revision 0)
195+++ src/history.c       (revision 0)
196@@ -0,0 +1,419 @@
197+/*
198+ * File: history.c
199+ * Purpose: Character auto-history creation, management, and display
200+ *
201+ * Copyright (c) 2007 J.D. White
202+ *
203+ * This work is free software; you can redistribute it and/or modify it
204+ * under the terms of either:
205+ *
206+ * a) the GNU General Public License as published by the Free Software
207+ *    Foundation, version 2, or
208+ *
209+ * b) the "Angband licence":
210+ *    This software may be copied and distributed for educational, research,
211+ *    and not for profit purposes provided that this copyright and statement
212+ *    are included in all such copies.  Other copyrights may also apply.
213+ */
214+#include "angband.h"
215+
216+
217+
218+/*
219+ * Number of slots available at birth in the player history list.  Defaults to
220+ * 10 and will expand automatically as new history entries are added, up the
221+ * the maximum defined value.
222+ */
223+#define HISTORY_BIRTH_SIZE  10
224+#define HISTORY_MAX 5000
225+
226+
227+
228+/* The historical list for the character */
229+history_info *history_list;
230+
231+/* Index of first writable entry */
232+static size_t history_ctr;
233+
234+/* Current size of history list */
235+static size_t history_size;
236+
237+
238+#define LIMITLOW(a, b) if (a < b) a = b;
239+#define LIMITHI(a, b) if (a > b) a = b;
240+
241+
242+
243+/*
244+ * Initialise an empty history list.
245+ */
246+static void history_init(size_t entries)
247+{
248+       if (history_list)
249+               FREE(history_list);
250+
251+       history_ctr = 0;
252+       history_size = entries;
253+       history_list = C_ZNEW(history_size, history_info);
254+}
255+
256+
257+/*
258+ * Clear any existing history.
259+ */
260+void history_clear(void)
261+{
262+       if (!history_list) return;
263+
264+       FREE(history_list);
265+       history_ctr = 0;
266+       history_size = 0;
267+}
268+
269+
270+/*
271+ * Set the number of history items.
272+ */
273+static bool history_set_num(size_t num)
274+{
275+       history_info *new_list;
276+
277+       if (num > HISTORY_MAX)
278+               num = HISTORY_MAX;
279+
280+       if (num < history_size)  return FALSE;
281+       if (num == history_size) return FALSE;
282+
283+       /* Allocate new memory, copy across */
284+       /* XXX Should use mem_realloc() */
285+       new_list = C_ZNEW(num, history_info);
286+       C_COPY(new_list, history_list, history_ctr, history_info);
287+       FREE(history_list);
288+
289+       history_list = new_list;
290+       history_size = num;
291+
292+       return TRUE;
293+}
294+
295+
296+/*
297+ * Return the number of history entries.
298+ */
299+size_t history_get_num(void)
300+{
301+       return history_ctr;
302+}
303+
304+
305+/*
306+ * Mark artifact number `id` as known.
307+ */
308+static bool history_know_artifact(byte a_idx)
309+{
310+       size_t i = history_ctr;
311+
312+       while (i--)
313+       {
314+               if (history_list[i].a_idx == a_idx)
315+               {
316+                       history_list[i].type = HISTORY_ARTIFACT_KNOWN;
317+                       return TRUE;
318+               }
319+       }
320+
321+       return FALSE;
322+}
323+
324+
325+/*
326+ * Mark artifact number `id` as lost forever, either due to leaving it on a
327+ * level, or due to a store purging its inventory after the player sold it.
328+ */
329+bool history_lose_artifact(byte a_idx)
330+{
331+       size_t i = history_ctr;
332+
333+       while (i--)
334+       {
335+               if (history_list[i].a_idx == a_idx)
336+               {
337+                       history_list[i].type |= HISTORY_ARTIFACT_LOST;
338+                       return TRUE;
339+               }
340+       }
341+
342+       return FALSE;
343+}
344+
345+
346+/*
347+ * Add an entry with text `event` to the history list, with type `type`
348+ * ("HISTORY_xxx" in defines.h), and artifact number `id` (0 for everything
349+ * else).
350+ *
351+ * Returne TRUE on success.
352+ */
353+bool history_add_full(u16b type, byte a_idx, s16b dlev, s16b clev, s32b turn, const char *text)
354+{
355+       /* Allocate the history list if needed */
356+       if (!history_list)
357+               history_init(HISTORY_BIRTH_SIZE);
358+
359+       /* Expand the history list if appropriate */
360+       else if ((history_ctr == history_size) && !history_set_num(history_size + 10))
361+               return FALSE;
362+
363+       /* History list exists and is not full.  Add an entry at the current counter location. */
364+       history_list[history_ctr].type = type;
365+       history_list[history_ctr].dlev = dlev;
366+       history_list[history_ctr].clev = clev;
367+       history_list[history_ctr].a_idx = a_idx;
368+       history_list[history_ctr].turn = turn;
369+       my_strcpy(history_list[history_ctr].event,
370+                 text, sizeof(history_list[history_ctr].event));
371+
372+       history_ctr++;
373+
374+       return TRUE;
375+}
376+
377+
378+/*
379+ * Add an entry with text `event` to the history list, with type `type`
380+ * ("HISTORY_xxx" in defines.h), and artifact number `id` (0 for everything
381+ * else).
382+ *
383+ * Returne TRUE on success.
384+ */
385+bool history_add(const char *event, u16b type, byte a_idx)
386+{
387+       return history_add_full(type, a_idx, p_ptr->depth, p_ptr->lev, turn, event);
388+}
389+
390+
391+/*
392+ * Returns TRUE if the artifact denoted by a_idx is an active entry in
393+ * the history log (i.e. is not marked HISTORY_ARTIFACT_LOST).  This permits
394+ * proper handling of the case where the player loses an artifact but (in
395+ * preserve mode) finds it again later.
396+ */
397+static bool history_is_artifact_logged(byte a_idx)
398+{
399+       size_t i = history_ctr;
400+
401+       while (i--)
402+       {
403+               /* Don't count ARTIFACT_LOST entries; then we can handle
404+                * re-finding previously lost artifacts in preserve mode  */
405+               if (history_list[i].type & HISTORY_ARTIFACT_LOST)
406+                       continue;
407+
408+               if (history_list[i].a_idx == a_idx)
409+                       return TRUE;
410+       }
411+
412+       return FALSE;
413+}
414+
415+
416+/*
417+ * Adding artifacts to the history list is trickier than other operations.
418+ * This is a wrapper function that gets some of the logic out of places
419+ * where it really doesn't belong.  Call this to add an artifact to the history
420+ * list or make the history entry visible--history_add_artifact will make that
421+ * determination depending on what object_known_p returns for the artifact.
422+ */
423+bool history_add_artifact(byte a_idx, bool known)
424+{
425+       object_type object_type_body;
426+       object_type *o_ptr = &object_type_body;
427+
428+       char o_name[80];
429+       char buf[80];
430+
431+       /* Make fake artifact for description purposes */
432+       object_wipe(o_ptr);
433+       make_fake_artifact(o_ptr, a_idx);
434+       object_desc_spoil(o_name, sizeof(o_name), o_ptr, TRUE, 0);
435+       strnfmt(buf, sizeof(buf), "Found %s", o_name);
436+
437+       /* Known objects gets different treatment */
438+       if (known)
439+       {
440+               /* Try revealing any existing artifact, otherwise log it */
441+               if (history_is_artifact_logged(a_idx))
442+                       history_know_artifact(a_idx);
443+               else
444+                       history_add(buf, HISTORY_ARTIFACT_KNOWN, a_idx);
445+       }
446+       else
447+       {
448+               if (!history_is_artifact_logged(a_idx))
449+                       history_add(buf, HISTORY_ARTIFACT_UNKNOWN, a_idx);
450+               else
451+                       return FALSE;
452+       }
453+
454+       return TRUE;
455+}
456+
457+
458+/*
459+ * Convert all ARTIFACT_UNKNOWN history items to HISTORY_ARTIFACT_KNOWN.
460+ * Use only after player retirement/death for the final character dump.
461+ */
462+void history_unmask_unknown(void)
463+{
464+       size_t i = history_ctr;
465+
466+       while (i--)
467+       {
468+               if (history_list[i].type & HISTORY_ARTIFACT_UNKNOWN)
469+               {
470+                       history_list[i].type &= ~(HISTORY_ARTIFACT_UNKNOWN);
471+                       history_list[i].type |= HISTORY_ARTIFACT_KNOWN;
472+               }
473+       }
474+}
475+
476+
477+/*
478+ * Used to determine whether the history entry is visible in the listing or not.
479+ * Returns TRUE if the item is masked -- that is, if it is invisible
480+ */
481+static bool history_masked(size_t i)
482+{
483+       if (history_list[i].type & HISTORY_ARTIFACT_UNKNOWN)
484+               return TRUE;
485+
486+       return FALSE;
487+}
488+
489+/*
490+ * Finds the index of the last printable (non-masked) item in the history list.
491+ */
492+static int last_printable_item(void)
493+{
494+       size_t i = history_ctr;
495+
496+       while (i--)
497+       {
498+               if (!history_masked(i))
499+                       break;
500+       }
501+
502+       return i;
503+}
504+
505+static void print_history_header(void)
506+{
507+       char buf[80];
508+
509+       /* Print the header (character name and title) */
510+       strnfmt(buf, sizeof(buf), "%s the %s %s",
511+               op_ptr->full_name,
512+               p_name + rp_ptr->name,
513+               c_name + cp_ptr->name);
514+
515+       c_put_str(TERM_WHITE, buf, 0, 0);
516+       c_put_str(TERM_WHITE, "============================================================", 1, 0);
517+       c_put_str(TERM_WHITE, "                   CHAR.  ", 2, 0);
518+       c_put_str(TERM_WHITE, "|   TURN  | DEPTH |LEVEL| EVENT", 3, 0);
519+       c_put_str(TERM_WHITE, "============================================================", 4, 0);
520+}
521+
522+
523+/* Handles all of the display functionality for the history list. */
524+void history_display(void)
525+{
526+       int row, wid, hgt, page_size;
527+       char buf[90];
528+       static int first_item = 0;
529+       int max_item = last_printable_item();
530+       size_t i;
531+
532+       Term_get_size(&wid, &hgt);
533+
534+       /* Six lines provide space for the header and footer */
535+       page_size = hgt - 6;
536+
537+       screen_save();
538+
539+       while (1)
540+       {
541+               char ch;
542+
543+               Term_clear();
544+
545+               /* Print everything to screen */
546+               print_history_header();
547+
548+               row = 0;
549+               for (i = first_item; row <= page_size && i < history_ctr; i++)
550+               {
551+                       /* Skip messages about artifacts not yet IDed. */
552+                       if (history_masked(i))
553+                               continue;
554+
555+                       strnfmt(buf, sizeof(buf), "%10d%7d\'%5d   %s",
556+                               history_list[i].turn,
557+                               history_list[i].dlev * 50,
558+                               history_list[i].clev,
559+                               history_list[i].event);
560+
561+                       if (history_list[i].type & HISTORY_ARTIFACT_LOST)
562+                               my_strcat(buf, " (LOST)", sizeof(buf));
563+
564+                       /* Size of header = 5 lines */
565+                       prt(buf, row + 5, 0);
566+                       row++;
567+               }
568+               prt("[Arrow keys scroll, p for previous page, n for next page, ESC to exit.]", hgt - 1, 0);
569+
570+               ch = inkey();
571+
572+               if (ch == 'n')
573+               {
574+                       first_item += page_size;
575+
576+                       while (history_masked(first_item) && first_item < history_ctr - 1)
577+                               first_item++;
578+
579+                       LIMITHI(first_item, max_item);
580+               }
581+               else if (ch == 'p')
582+               {
583+                       first_item -= page_size;
584+
585+                       while (history_masked(first_item) && first_item > 0)
586+                               first_item--;
587+
588+                       LIMITLOW(first_item, 0);
589+               }
590+               else if (ch == ARROW_DOWN)
591+               {
592+                       first_item++;
593+
594+                       while (history_masked(first_item) && first_item < history_ctr - 1)
595+                               first_item++;
596+
597+                       LIMITHI(first_item, max_item);
598+               }
599+               else if (ch == ARROW_UP)
600+               {
601+                       first_item--;
602+
603+                       while (history_masked(first_item) && first_item > 0)
604+                               first_item--;
605+
606+                       LIMITLOW(first_item, 0);
607+               }
608+               else if (ch == ESCAPE)
609+                       break;
610+       }
611+
612+       screen_load();
613+
614+       return;
615+}
616Index: src/cmd4.c
617===================================================================
618--- src/cmd4.c  (revision 635)
619+++ src/cmd4.c  (working copy)
620@@ -19,6 +19,7 @@
621 #include "angband.h"
622 #include "option.h"
623 #include "ui.h"
624+#include "externs.h"
625 #include "ui-menu.h"
626 
627 
628@@ -4062,6 +4063,12 @@
629        show_scores();
630 }
631 
632+static void do_cmd_knowledge_history(void *obj, const char *name)
633+{
634+       history_display();     
635+}
636+
637+
638 /*
639  * Definition of the "player knowledge" menu.
640  */
641@@ -4074,6 +4081,7 @@
642        {{0, "Display feature knowledge", do_cmd_knowledge_features, 0}, 'e'},
643        {{0, "Display self-knowledge", do_cmd_self_knowledge, 0}, 'f'},
644        {{0, "Display hall of fame", do_cmd_knowledge_scores, 0}, 'g'},
645+       {{0, "Display character history", do_cmd_knowledge_history, 0}, 'h'},
646 };
647 
648 static menu_type knowledge_menu;
649@@ -4253,6 +4261,9 @@
650 
651        /* Add the note to the message recall */
652        msg_format("Note: %s", tmp);
653+
654+       /* Add a history entry */
655+       history_add(tmp, HISTORY_USER_INPUT, 0);
656 }
657 
658 
659Index: src/xtra2.c
660===================================================================
661--- src/xtra2.c (revision 635)
662+++ src/xtra2.c (working copy)
663@@ -991,12 +991,22 @@
664               (p_ptr->exp >= (player_exp[p_ptr->lev-1] *
665                               p_ptr->expfact / 100L)))
666        {
667+               char buf[80];
668+               
669                /* Gain a level */
670                p_ptr->lev++;
671 
672                /* Save the highest level */
673-               if (p_ptr->lev > p_ptr->max_lev) p_ptr->max_lev = p_ptr->lev;
674+               if (p_ptr->lev > p_ptr->max_lev)
675+               {
676+                       p_ptr->max_lev = p_ptr->lev;
677 
678+                       /* Log level updates (TODO: perhaps only every other level or every 5) */
679+                       strnfmt(buf, sizeof(buf), "Reached level %d", p_ptr->lev);
680+                       history_add(buf, HISTORY_GAIN_LEVEL, 0);
681+                       
682+               }
683+                       
684                /* Message */
685                message_format(MSG_LEVEL, p_ptr->lev, "Welcome to level %d.", p_ptr->lev);
686 
687@@ -1408,6 +1418,7 @@
688        if (m_ptr->hp < 0)
689        {
690                char m_name[80];
691+               char buf[80];
692 
693                /* Assume normal death sound */
694                int soundfx = MSG_KILL;
695@@ -1473,6 +1484,20 @@
696                        p_ptr->exp_frac = (u16b)new_exp_frac;
697                }
698 
699+               /* When the player kills a Unique, it stays dead */
700+               if (r_ptr->flags1 & (RF1_UNIQUE))
701+               {
702+                       char unique_name[80];
703+                       r_ptr->max_num = 0;
704+                       
705+                       /* This gets the correct name if we slay an invisible unique and don't have See Invisible. */
706+                       monster_desc(unique_name, sizeof(unique_name), m_ptr, 0x88);
707+
708+                       /* Log the slaying of a unique */
709+                       strnfmt(buf, sizeof(buf), "Killed %s", unique_name);
710+                       history_add(buf, HISTORY_SLAY_UNIQUE, 0);
711+               }
712+                       
713                /* Gain experience */
714                gain_exp(new_exp);
715 
716Index: src/store.c
717===================================================================
718--- src/store.c (revision 635)
719+++ src/store.c (working copy)
720@@ -1077,6 +1077,10 @@
721 
722        }
723 
724+       /* Is the item an artifact? Mark it as lost if the player has it in history list */
725+       if (artifact_p(o_ptr))
726+               history_lose_artifact(o_ptr->name1);
727+
728        /* Delete the item */
729        store_item_increase(st, what, -num);
730        store_item_optimize(st, what);
731@@ -2224,6 +2228,10 @@
732                object_aware(o_ptr);
733                object_known(o_ptr);
734 
735+               /* Update the auto-history if selling an artifact that was previously un-IDed. (Ouch!) */
736+               if (artifact_p(o_ptr))
737+                       history_add_artifact(o_ptr->name1, TRUE);
738+
739                /* Combine / Reorder the pack (later) */
740                p_ptr->notice |= (PN_COMBINE | PN_REORDER);
741 
742Index: src/types.h
743===================================================================
744--- src/types.h (revision 635)
745+++ src/types.h (working copy)
746@@ -90,6 +90,7 @@
747 typedef struct player_type player_type;
748 typedef struct start_item start_item;
749 typedef struct autoinscription autoinscription;
750+typedef struct history_info history_info;
751 
752 
753 /**** Available structs ****/
754@@ -1034,7 +1035,7 @@
755 
756        s16b pspeed;            /* Current speed */
757 
758-    /* Generation fields (for quick start) */
759+       /* Generation fields (for quick start) */
760        s32b au_birth;          /* Birth gold */
761        s16b stat_birth[A_MAX]; /* Birth "natural" stat values */
762        s16b ht_birth;          /* Birth Height */
763@@ -1115,6 +1116,16 @@
764 };
765 
766 
767+struct history_info
768+{
769+       u16b type;                      /* Kind of history item */
770+       s16b dlev;                      /* Dungeon level when this item was recorded */
771+       s16b clev;                      /* Character level when this item was recorded */
772+       byte a_idx;                     /* Artifact this item relates to */
773+       s32b turn;                      /* Turn this item was recorded on */
774+       char event[80]; /* The text of the item */
775+};
776+
777 enum grid_light_level
778 {
779        LIGHT_TORCH,
780Index: src/cmd1.c
781===================================================================
782--- src/cmd1.c  (revision 635)
783+++ src/cmd1.c  (working copy)
784@@ -284,6 +284,10 @@
785                msg_format("You have %s (%c).", o_name, index_to_label(slot));
786        }
787 
788+       /* Log if picking up an artifact. */
789+       if (artifact_p(o_ptr))
790+               history_add_artifact(o_ptr->name1, object_known_p(o_ptr));
791+
792        /* Delete the object */
793        delete_object_idx(o_idx);
794 }
795Index: src/object2.c
796===================================================================
797--- src/object2.c       (revision 635)
798+++ src/object2.c       (working copy)
799@@ -464,6 +464,10 @@
800                                a_info[o_ptr->name1].cur_num = 0;
801                }
802 
803+               /* Mark artifacts as lost in logs */
804+               if (artifact_p(o_ptr))
805+                       history_lose_artifact(o_ptr->name1);
806+
807                /* Monster */
808                if (o_ptr->held_m_idx)
809                {
810Index: src/save.c
811===================================================================
812--- src/save.c  (revision 635)
813+++ src/save.c  (working copy)
814@@ -813,8 +813,8 @@
815        u32b now;
816 
817        u16b tmp16u;
818+       u32b tmp32u;
819 
820-
821        /* Guess at the current time */
822        now = time((time_t *)0);
823 
824@@ -995,7 +995,23 @@
825                wr_ghost();
826        }
827 
828+       /* NEW (jdw): dumping history entries */
829+       /* Dump the number of history entries */
830+       tmp32u = history_get_num();
831+       wr_u32b(tmp32u);
832 
833+       /* Dump the history entries one-by-one */
834+       for (i = 0; i < tmp32u; i++)
835+       {
836+               wr_u16b(history_list[i].type);
837+               wr_s32b(history_list[i].turn);
838+               wr_s16b(history_list[i].dlev);
839+               wr_s16b(history_list[i].clev);
840+               wr_byte(history_list[i].a_idx);
841+               wr_string(history_list[i].event);
842+       }
843+
844+
845        /* Write the "value check-sum" */
846        wr_u32b(v_stamp);
847 
848Index: src/spells2.c
849===================================================================
850--- src/spells2.c       (revision 635)
851+++ src/spells2.c       (working copy)
852@@ -3689,6 +3689,10 @@
853                sound(MSG_IDENT_EGO);
854        }
855 
856+       /* Log artifacts to the history list. */
857+       if (artifact_p(o_ptr))
858+               history_add_artifact(o_ptr->name1, TRUE);
859+
860        /* Describe */
861        if (item >= INVEN_WIELD)
862        {