1 /*
2  *  File:       tags.cc
3  *  Summary:    Auxilary functions to make savefile versioning simpler.
4  *  Written by: Gordon Lipford
5  *
6  *  Change History (most recent first):
7  *
8  *   <2>   16 Mar 2001      GDL    Added TAG_LEVEL_ATTITUDE
9  *   <1>   27 Jan 2001      GDL    Created
10  */
11 
12 /* ------------------------- how tags work ----------------------------------
13 
14 1. Tag types are enumerated in enum.h, from TAG_VERSION (more a placeholder
15    than anything else, it is not actually saved as a tag) to TAG_XXX. NUM_TAGS
16    is equal to the actual number of defined tags.
17 
18 2. Tags are created with tag_construct(),  which forwards the construction
19    request appropriately.   tag_write() is then used to write the tag to an
20    output stream.
21 
22 3. Tags are parsed with tag_read(), which tries to read a tag header and then
23    forwards the request appropriately, returning the ID of the tag it found,
24    or zero if no tag was found.
25 
26 4. In order to know which tags are used by a particular file type,  a client
27    calls tag_set_expected( fileType ), which sets up an array of chars.
28    Within the array, a value of 1 means the tag is expected; -1 means that
29    the tag is not expected.  A client can then set values in this array to
30    anything other than 1 to indicate a successful tag_read() of that tag.
31 
32 5. A case should be provided in tag_missing() for any tag which might be
33    missing from a tagged save file.  For example,  if a developer adds
34    TAG_YOU_NEW_STUFF to the player save file,  he would have to provide a
35    case in tag_missing() for this tag since it might not be there in
36    earlier savefiles.   The tags defined with the original tag system (and
37    so not needing cases in tag_missing()) are as follows:
38 
39     TAG_YOU = 1,              // 'you' structure
40     TAG_YOU_ITEMS,            // your items
41     TAG_YOU_DUNGEON,          // dungeon specs (stairs, branches, features)
42     TAG_LEVEL,                // various grids & clouds
43     TAG_LEVEL_ITEMS,          // items/traps
44     TAG_LEVEL_MONSTERS,       // monsters
45     TAG_GHOST,                // ghost
46 
47 6. The marshalling and unmarshalling of data is done in network order and
48    is meant to keep savefiles cross-platform.  They are non-ascii - always
49    FTP in binary mode.  Note also that the marshalling sizes are 1,2, and 4
50    for byte, short, and long - assuming that 'int' would have been
51    insufficient on 16 bit systems (and that Crawl otherwise lacks
52    system-indepedent data types).
53 
54 */
55 
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <string.h>            // for memcpy
59 
60 #ifdef LINUX
61 #include <sys/types.h>
62 #include <sys/stat.h>
63 #include <fcntl.h>
64 #include <unistd.h>
65 #endif
66 
67 #ifdef USE_EMX
68 #include <sys/types.h>
69 #include <fcntl.h>
70 #include <unistd.h>
71 #endif
72 
73 #ifdef OS9
74 #include <stat.h>
75 #else
76 #include <sys/stat.h>
77 #endif
78 
79 #include "AppHdr.h"
80 
81 #include "abl-show.h"
82 #include "enum.h"
83 #include "externs.h"
84 #include "files.h"
85 #include "itemname.h"
86 #include "monstuff.h"
87 #include "mon-util.h"
88 #include "randart.h"
89 #include "skills.h"
90 #include "skills2.h"
91 #include "stuff.h"
92 #include "tags.h"
93 
94 // THE BIG IMPORTANT TAG CONSTRUCTION/PARSE BUFFER
95 static char *tagBuffer = NULL;
96 
97 // These three are defined in overmap.cc
98 extern FixedArray < unsigned char, MAX_LEVELS, MAX_BRANCHES > altars_present;
99 extern FixedVector < char, MAX_BRANCHES > stair_level;
100 extern FixedArray < unsigned char, MAX_LEVELS, MAX_BRANCHES > feature;
101 
102 extern unsigned char your_sign; /* these two are defined in view.cc */
103 extern unsigned char your_colour;
104 
105 // temp file pairs used for file level cleanup
106 FixedArray < bool, MAX_LEVELS, MAX_BRANCHES > tmp_file_pairs;
107 
108 
109 // static helpers
110 static void tag_construct_you(struct tagHeader &th);
111 static void tag_construct_you_items(struct tagHeader &th);
112 static void tag_construct_you_dungeon(struct tagHeader &th);
113 static void tag_read_you(struct tagHeader &th, char minorVersion);
114 static void tag_read_you_items(struct tagHeader &th, char minorVersion);
115 static void tag_read_you_dungeon(struct tagHeader &th);
116 
117 static void tag_construct_level(struct tagHeader &th);
118 static void tag_construct_level_items(struct tagHeader &th);
119 static void tag_construct_level_monsters(struct tagHeader &th);
120 static void tag_construct_level_attitude(struct tagHeader &th);
121 static void tag_read_level(struct tagHeader &th, char minorVersion);
122 static void tag_read_level_items(struct tagHeader &th, char minorVersion);
123 static void tag_read_level_monsters(struct tagHeader &th, char minorVersion);
124 static void tag_read_level_attitude(struct tagHeader &th);
125 static void tag_missing_level_attitude();
126 
127 static void tag_construct_ghost(struct tagHeader &th);
128 static void tag_read_ghost(struct tagHeader &th, char minorVersion);
129 
130 // provide a wrapper for file writing, just in case.
write2(FILE * file,char * buffer,unsigned int count)131 int write2(FILE * file, char *buffer, unsigned int count)
132 {
133     return fwrite(buffer, 1, count, file);
134 }
135 
136 // provide a wrapper for file reading, just in case.
read2(FILE * file,char * buffer,unsigned int count)137 int read2(FILE * file, char *buffer, unsigned int count)
138 {
139     return fread(buffer, 1, count, file);
140 }
141 
marshallByte(struct tagHeader & th,char data)142 void marshallByte(struct tagHeader &th, char data)
143 {
144     tagBuffer[th.offset] = data;
145     th.offset += 1;
146 }
147 
unmarshallByte(struct tagHeader & th)148 char unmarshallByte(struct tagHeader &th)
149 {
150     char data = tagBuffer[th.offset];
151     th.offset += 1;
152     return data;
153 }
154 
155 // marshall 2 byte short in network order
marshallShort(struct tagHeader & th,short data)156 void marshallShort(struct tagHeader &th, short data)
157 {
158     char b2 = (char)(data & 0x00FF);
159     char b1 = (char)((data & 0xFF00) >> 8);
160 
161     tagBuffer[th.offset] = b1;
162     tagBuffer[th.offset + 1] = b2;
163 
164     th.offset += 2;
165 }
166 
167 // unmarshall 2 byte short in network order
unmarshallShort(struct tagHeader & th)168 short unmarshallShort(struct tagHeader &th)
169 {
170     short b1 = tagBuffer[th.offset];
171     short b2 = tagBuffer[th.offset + 1];
172 
173     short data = (b1 << 8) | (b2 & 0x00FF);
174 
175     th.offset += 2;
176     return data;
177 }
178 
179 // marshall 4 byte int in network order
marshallLong(struct tagHeader & th,long data)180 void marshallLong(struct tagHeader &th, long data)
181 {
182     char b4 = (char) (data & 0x000000FF);
183     char b3 = (char)((data & 0x0000FF00) >> 8);
184     char b2 = (char)((data & 0x00FF0000) >> 16);
185     char b1 = (char)((data & 0xFF000000) >> 24);
186 
187     tagBuffer[th.offset] = b1;
188     tagBuffer[th.offset + 1] = b2;
189     tagBuffer[th.offset + 2] = b3;
190     tagBuffer[th.offset + 3] = b4;
191 
192     th.offset += 4;
193 }
194 
195 // unmarshall 4 byte int in network order
unmarshallLong(struct tagHeader & th)196 long unmarshallLong(struct tagHeader &th)
197 {
198     long b1 = tagBuffer[th.offset];
199     long b2 = tagBuffer[th.offset + 1];
200     long b3 = tagBuffer[th.offset + 2];
201     long b4 = tagBuffer[th.offset + 3];
202 
203     long data = (b1 << 24) | ((b2 & 0x000000FF) << 16);
204     data |= ((b3 & 0x000000FF) << 8) | (b4 & 0x000000FF);
205 
206     th.offset += 4;
207     return data;
208 }
209 
210 // single precision float -- marshall in network order.
marshallFloat(struct tagHeader & th,float data)211 void marshallFloat(struct tagHeader &th, float data)
212 {
213     long intBits = *((long *)(&data));
214     marshallLong(th, intBits);
215 }
216 
217 // single precision float -- unmarshall in network order.
unmarshallFloat(struct tagHeader & th)218 float unmarshallFloat(struct tagHeader &th)
219 {
220     long intBits = unmarshallLong(th);
221 
222     return *((float *)(&intBits));
223 }
224 
225 // string -- marshall length & string data
marshallString(struct tagHeader & th,char * data,int maxSize)226 void marshallString(struct tagHeader &th, char *data, int maxSize)
227 {
228     // allow for very long strings.
229     short len = strlen(data);
230     if (maxSize > 0 && len > maxSize)
231         len = maxSize;
232     marshallShort(th, len);
233 
234     // put in the actual string -- we'll null terminate on
235     // unmarshall.
236     memcpy(&tagBuffer[th.offset], data, len);
237 
238     th.offset += len;
239 }
240 
241 // string -- unmarshall length & string data
unmarshallString(struct tagHeader & th,char * data,int maxSize)242 void unmarshallString(struct tagHeader &th, char *data, int maxSize)
243 {
244     // get length
245     short len = unmarshallShort(th);
246     int copylen = len;
247     if (len > maxSize && maxSize > 0)
248         copylen = maxSize;
249 
250     // read the actual string and null terminate
251     memcpy(data, &tagBuffer[th.offset], copylen);
252     data[copylen] = '\0';
253 
254     th.offset += len;
255 }
256 
257 // boolean (to avoid system-dependant bool implementations)
marshallBoolean(struct tagHeader & th,bool data)258 void marshallBoolean(struct tagHeader &th, bool data)
259 {
260     char charRep = 0;       // for false
261     if (data)
262         charRep = 1;
263 
264     tagBuffer[th.offset] = charRep;
265     th.offset += 1;
266 }
267 
268 // boolean (to avoid system-dependant bool implementations)
unmarshallBoolean(struct tagHeader & th)269 bool unmarshallBoolean(struct tagHeader &th)
270 {
271     bool data;
272 
273     if (tagBuffer[th.offset] == 1)
274         data = true;
275     else
276         data = false;
277 
278     th.offset += 1;
279     return data;
280 }
281 
282 // Saving the date as a string so we're not reliant on a particular epoch.
make_date_string(time_t in_date,char buff[20])283 void make_date_string( time_t in_date, char buff[20] )
284 {
285     if (in_date <= 0)
286     {
287         buff[0] = '\0';
288         return;
289     }
290 
291 
292     struct tm *date = localtime( &in_date );
293 
294     snprintf( buff, 20,
295               "%4d%02d%02d%02d%02d%02d%s",
296               date->tm_year + 1900, date->tm_mon, date->tm_mday,
297               date->tm_hour, date->tm_min, date->tm_sec,
298               ((date->tm_isdst > 0) ? "D" : "S") );
299 }
300 
get_val_from_string(const char * ptr,int len)301 static int get_val_from_string( const char *ptr, int len )
302 {
303     int ret = 0;
304     int pow = 1;
305 
306     for (const char *chr = ptr + len - 1; chr >= ptr; chr--)
307     {
308         ret += (*chr - '0') * pow;
309         pow *= 10;
310     }
311 
312     return (ret);
313 }
314 
parse_date_string(char buff[20])315 time_t parse_date_string( char buff[20] )
316 {
317     struct tm date;
318 
319     date.tm_year = get_val_from_string( &buff[0],  4 ) - 1900;
320     date.tm_mon  = get_val_from_string( &buff[4],  2 );
321     date.tm_mday = get_val_from_string( &buff[6],  2 );
322     date.tm_hour = get_val_from_string( &buff[8],  2 );
323     date.tm_min  = get_val_from_string( &buff[10], 2 );
324     date.tm_sec  = get_val_from_string( &buff[12], 2 );
325 
326     date.tm_isdst = (buff[14] == 'D');
327 
328     return (mktime( &date ));
329 }
330 
331 // PUBLIC TAG FUNCTIONS
tag_init(long largest_tag)332 void tag_init(long largest_tag)
333 {
334     if (tagBuffer != NULL)
335         return;
336 
337     tagBuffer = (char *)malloc(largest_tag);
338 }
339 
tag_construct(struct tagHeader & th,int tagID)340 void tag_construct(struct tagHeader &th, int tagID)
341 {
342     th.offset = 0;
343     th.tagID = tagID;
344 
345     switch(tagID)
346     {
347         case TAG_YOU:
348             tag_construct_you(th);
349             break;
350         case TAG_YOU_ITEMS:
351             tag_construct_you_items(th);
352             break;
353         case TAG_YOU_DUNGEON:
354             tag_construct_you_dungeon(th);
355             break;
356         case TAG_LEVEL:
357             tag_construct_level(th);
358             break;
359         case TAG_LEVEL_ITEMS:
360             tag_construct_level_items(th);
361             break;
362         case TAG_LEVEL_MONSTERS:
363             tag_construct_level_monsters(th);
364             break;
365         case TAG_LEVEL_ATTITUDE:
366             tag_construct_level_attitude(th);
367             break;
368         case TAG_GHOST:
369             tag_construct_ghost(th);
370             break;
371         default:
372             // I don't know how to make that!
373             break;
374     }
375 }
376 
tag_write(struct tagHeader & th,FILE * saveFile)377 void tag_write(struct tagHeader &th, FILE *saveFile)
378 {
379     const int tagHdrSize = 6;
380     int tagSize=0;
381 
382     char swap[tagHdrSize];
383 
384     // make sure there is some data to write!
385     if (th.offset == 0)
386         return;
387 
388     // special case: TAG_VERSION.  Skip tag header.
389     if (th.tagID != TAG_VERSION)
390     {
391         // swap out first few bytes
392         memcpy(swap, tagBuffer, tagHdrSize);
393 
394         // save tag size
395         tagSize = th.offset;
396 
397         // swap in the header
398         th.offset = 0;
399         marshallShort(th, th.tagID);
400         marshallLong(th, tagSize);
401 
402         // write header
403         write2(saveFile, tagBuffer, th.offset);
404 
405         // swap real data back in
406         memcpy(tagBuffer, swap, tagHdrSize);
407 
408         // reset tag size
409         th.offset = tagSize;
410     }
411 
412     // write tag data
413     write2(saveFile, tagBuffer, th.offset);
414     return;
415 }
416 
417 // minorVersion is available for any sub-readers that need it
418 // (like TAG_LEVEL_MONSTERS)
tag_read(FILE * fp,char minorVersion)419 int tag_read(FILE *fp, char minorVersion)
420 {
421     const int tagHdrSize = 6;
422     struct tagHeader hdr, th;
423     th.offset = 0;
424 
425     // read tag header
426     if (read2(fp, tagBuffer, tagHdrSize) != tagHdrSize)
427         return 0;
428 
429     // unmarshall tag type and length (not including header)
430     hdr.tagID = unmarshallShort(th);
431     hdr.offset = unmarshallLong(th);
432 
433     // sanity check
434     if (hdr.tagID <= 0 || hdr.offset <= 0)
435         return 0;
436 
437     // now reset th and read actual data
438     th.offset = 0;
439     if (read2(fp, tagBuffer, hdr.offset) != hdr.offset)
440         return 0;
441 
442     // ok, we have data now.
443     switch(hdr.tagID)
444     {
445         case TAG_YOU:
446             tag_read_you(th, minorVersion);
447             break;
448         case TAG_YOU_ITEMS:
449             tag_read_you_items(th, minorVersion);
450             break;
451         case TAG_YOU_DUNGEON:
452             tag_read_you_dungeon(th);
453             break;
454         case TAG_LEVEL:
455             tag_read_level(th, minorVersion);
456             break;
457         case TAG_LEVEL_ITEMS:
458             tag_read_level_items(th, minorVersion);
459             break;
460         case TAG_LEVEL_MONSTERS:
461             tag_read_level_monsters(th, minorVersion);
462             break;
463         case TAG_LEVEL_ATTITUDE:
464             tag_read_level_attitude(th);
465             break;
466         case TAG_GHOST:
467             tag_read_ghost(th, minorVersion);
468             break;
469         default:
470             // I don't know how to read that!
471             return 0;
472     }
473 
474     return hdr.tagID;
475 }
476 
477 
478 // older savefiles might want to call this to get a tag
479 // properly initialized if it wasn't part of the savefile.
480 // For now, none are supported.
481 
482 // This function will be called AFTER all other tags for
483 // the savefile are read,  so everything that can be
484 // initialized should have been by now.
485 
486 // minorVersion is available for any child functions that need
487 // it (currently none)
tag_missing(int tag,char minorVersion)488 void tag_missing(int tag, char minorVersion)
489 {
490     UNUSED( minorVersion );
491 
492     switch(tag)
493     {
494         case TAG_LEVEL_ATTITUDE:
495             tag_missing_level_attitude();
496             break;
497         default:
498             perror("Tag %d is missing;  file is likely corrupt.");
499             end(-1);
500     }
501 }
502 
503 // utility
tag_set_expected(char tags[],int fileType)504 void tag_set_expected(char tags[], int fileType)
505 {
506     int i;
507 
508     for(i=0; i<NUM_TAGS; i++)
509     {
510         tags[i] = -1;
511         switch(fileType)
512         {
513             case TAGTYPE_PLAYER:
514                 if (i >= TAG_YOU && i <=TAG_YOU_DUNGEON)
515                     tags[i] = 1;
516                 break;
517             case TAGTYPE_LEVEL:
518                 if (i >= TAG_LEVEL && i <= TAG_LEVEL_ATTITUDE)
519                     tags[i] = 1;
520                 break;
521             case TAGTYPE_GHOST:
522                 if (i == TAG_GHOST)
523                     tags[i] = 1;
524             default:
525                 // I don't know what kind of file that is!
526                 break;
527         }
528     }
529 }
530 
531 // NEVER _MODIFY_ THE CONSTRUCT/READ FUNCTIONS,  EVER.  THAT IS THE WHOLE POINT
532 // OF USING TAGS.  Apologies for the screaming.
533 
534 // Note anyway that the formats are somewhat flexible;  you could change map
535 // size,  the # of slots in player inventory,  etc.  Constants like GXM,
536 // NUM_EQUIP, and NUM_DURATIONS are saved,  so the appropriate amount will
537 // be restored even if a later version increases these constants.
538 
539 // --------------------------- player tags (foo.sav) -------------------- //
tag_construct_you(struct tagHeader & th)540 static void tag_construct_you(struct tagHeader &th)
541 {
542     char buff[20];      // used for date string
543     int i,j;
544 
545     marshallString(th, you.your_name, 30);
546 
547     marshallByte(th,you.religion);
548     marshallByte(th,you.piety);
549     marshallByte(th,you.invis);
550     marshallByte(th,you.conf);
551     marshallByte(th,you.paralysis);
552     marshallByte(th,you.slow);
553     marshallByte(th,you.fire_shield);
554     marshallByte(th,you.rotting);
555     marshallByte(th,you.exhausted);
556     marshallByte(th,you.deaths_door);
557     marshallByte(th,your_sign);
558     marshallByte(th,your_colour);
559     marshallByte(th,you.pet_target);
560 
561     marshallByte(th,you.max_level);
562     marshallByte(th,you.where_are_you);
563     marshallByte(th,you.char_direction);
564     marshallByte(th,you.your_level);
565     marshallByte(th,you.is_undead);
566     marshallByte(th,you.special_wield);
567     marshallByte(th,you.berserker);
568     marshallByte(th,you.berserk_penalty);
569     marshallByte(th,you.level_type);
570     marshallByte(th,you.synch_time);
571     marshallByte(th,you.disease);
572     marshallByte(th,you.species);
573 
574     marshallShort(th, you.hp);
575 
576     if (you.haste > 215)
577         you.haste = 215;
578 
579     marshallByte(th,you.haste);
580 
581     if (you.might > 215)
582         you.might = 215;
583 
584     marshallByte(th,you.might);
585 
586     if (you.levitation > 215)
587         you.levitation = 215;
588 
589     marshallByte(th,you.levitation);
590 
591     if (you.poison > 215)
592         you.poison = 215;
593 
594     marshallByte(th,you.poison);
595 
596     marshallShort(th, you.hunger);
597 
598     // how many you.equip?
599     marshallByte(th, NUM_EQUIP);
600     for (i = 0; i < NUM_EQUIP; ++i)
601         marshallByte(th,you.equip[i]);
602 
603     marshallByte(th,you.magic_points);
604     marshallByte(th,you.max_magic_points);
605     marshallByte(th,you.strength);
606     marshallByte(th,you.intel);
607     marshallByte(th,you.dex);
608     marshallByte(th,you.confusing_touch);
609     marshallByte(th,you.sure_blade);
610     marshallByte(th,you.hit_points_regeneration);
611     marshallByte(th,you.magic_points_regeneration);
612 
613     marshallShort(th, you.hit_points_regeneration * 100);
614     marshallLong(th, you.experience);
615     marshallLong(th, you.gold);
616 
617     marshallByte(th,you.char_class);
618     marshallByte(th,you.experience_level);
619     marshallLong(th, you.exp_available);
620 
621     /* max values */
622     marshallByte(th,you.max_strength);
623     marshallByte(th,you.max_intel);
624     marshallByte(th,you.max_dex);
625 
626     marshallShort(th, you.base_hp);
627     marshallShort(th, you.base_hp2);
628     marshallShort(th, you.base_magic_points);
629     marshallShort(th, you.base_magic_points2);
630 
631     marshallShort(th, you.x_pos);
632     marshallShort(th, you.y_pos);
633 
634     marshallString(th, you.class_name, 30);
635 
636     marshallShort(th, you.burden);
637 
638     // how many spells?
639     marshallByte(th, 25);
640     for (i = 0; i < 25; ++i)
641         marshallByte(th, you.spells[i]);
642 
643     marshallByte(th, 52);
644     for (i = 0; i < 52; i++)
645         marshallByte( th, you.spell_letter_table[i] );
646 
647     marshallByte(th, 52);
648     for (i = 0; i < 52; i++)
649         marshallShort( th, you.ability_letter_table[i] );
650 
651     // how many skills?
652     marshallByte(th, 50);
653     for (j = 0; j < 50; ++j)
654     {
655         marshallByte(th,you.skills[j]);   /* skills! */
656         marshallByte(th,you.practise_skill[j]);   /* skills! */
657         marshallLong(th,you.skill_points[j]);
658         marshallByte(th,you.skill_order[j]);   /* skills ordering */
659     }
660 
661     // how many durations?
662     marshallByte(th, NUM_DURATIONS);
663     for (j = 0; j < NUM_DURATIONS; ++j)
664         marshallByte(th,you.duration[j]);
665 
666     // how many attributes?
667     marshallByte(th, 30);
668     for (j = 0; j < 30; ++j)
669         marshallByte(th,you.attribute[j]);
670 
671     // how many mutations/demon powers?
672     marshallShort(th, 100);
673     for (j = 0; j < 100; ++j)
674     {
675         marshallByte(th,you.mutation[j]);
676         marshallByte(th,you.demon_pow[j]);
677     }
678 
679     // how many penances?
680     marshallByte(th, MAX_NUM_GODS);
681     for (i = 0; i < MAX_NUM_GODS; i++)
682         marshallByte(th, you.penance[i]);
683 
684     // which gods have been worshipped by this character?
685     marshallByte(th, MAX_NUM_GODS);
686     for (i = 0; i < MAX_NUM_GODS; i++)
687         marshallByte(th, you.worshipped[i]);
688 
689     marshallByte(th, you.gift_timeout);
690     marshallByte(th, you.normal_vision);
691     marshallByte(th, you.current_vision);
692     marshallByte(th, you.hell_exit);
693 
694     // elapsed time
695     marshallFloat(th, (float)you.elapsed_time);
696 
697     // wizard mode used
698     marshallByte(th, you.wizard);
699 
700     // time of game start
701     make_date_string( you.birth_time, buff );
702     marshallString(th, buff, 20);
703 
704     // real_time == -1 means game was started before this feature
705     if (you.real_time != -1)
706     {
707         const time_t now = time(NULL);
708         you.real_time += (now - you.start_time);
709 
710         // Reset start_time now that real_time is being saved out...
711         // this may just be a level save.
712         you.start_time = now;
713     }
714 
715     marshallLong( th, you.real_time );
716     marshallLong( th, you.num_turns );
717 }
718 
tag_construct_you_items(struct tagHeader & th)719 static void tag_construct_you_items(struct tagHeader &th)
720 {
721     int i,j;
722 
723     // how many inventory slots?
724     marshallByte(th, ENDOFPACK);
725     for (i = 0; i < ENDOFPACK; ++i)
726     {
727         marshallByte(th,you.inv[i].base_type);
728         marshallByte(th,you.inv[i].sub_type);
729         marshallShort(th,you.inv[i].plus);
730         marshallLong(th,you.inv[i].special);
731         marshallByte(th,you.inv[i].colour);
732         marshallLong(th,you.inv[i].flags);
733         marshallShort(th,you.inv[i].quantity);
734         marshallShort(th,you.inv[i].plus2);
735     }
736 
737     // item descrip for each type & subtype
738     // how many types?
739     marshallByte(th, 5);
740     // how many subtypes?
741     marshallByte(th, 50);
742     for (i = 0; i < 5; ++i)
743     {
744         for (j = 0; j < 50; ++j)
745             marshallByte(th, you.item_description[i][j]);
746     }
747 
748     // identification status
749     // how many types?
750     marshallByte(th, 4);
751     // how many subtypes?
752     marshallByte(th, 50);
753 
754     // this is really dumb. We copy the id[] array from itemname
755     // to the stack,  for no good reason that I can see.
756     char identy[4][50];
757 
758     save_id(identy);
759 
760     for (i = 0; i < 4; ++i)
761     {
762         for (j = 0; j < 50; ++j)
763             marshallByte(th, identy[i][j]);
764     }
765 
766     // how many unique items?
767     marshallByte(th, 50);
768     for (j = 0; j < 50; ++j)
769     {
770         marshallByte(th,you.unique_items[j]);     /* unique items */
771         marshallByte(th,you.had_book[j]);
772     }
773 
774     // how many unrandarts?
775     marshallShort(th, NO_UNRANDARTS);
776 
777     for (j = 0; j < NO_UNRANDARTS; ++j)
778         marshallBoolean(th, does_unrandart_exist(j));
779 }
780 
tag_construct_you_dungeon(struct tagHeader & th)781 static void tag_construct_you_dungeon(struct tagHeader &th)
782 {
783     int i,j;
784 
785     // how many unique creatures?
786     marshallByte(th, 50);
787     for (j = 0; j < 50; ++j)
788         marshallByte(th,you.unique_creatures[j]); /* unique beasties */
789 
790     // how many branches?
791     marshallByte(th, MAX_BRANCHES);
792     for (j = 0; j < 30; ++j)
793     {
794         marshallByte(th,you.branch_stairs[j]);
795         marshallByte(th,stair_level[j]);
796     }
797 
798     // how many levels?
799     marshallShort(th, MAX_LEVELS);
800     for (i = 0; i < MAX_LEVELS; ++i)
801     {
802         for (j = 0; j < MAX_BRANCHES; ++j)
803         {
804             marshallByte(th,altars_present[i][j]);
805             marshallByte(th,feature[i][j]);
806             marshallBoolean(th,tmp_file_pairs[i][j]);
807         }
808     }
809 }
810 
tag_read_you(struct tagHeader & th,char minorVersion)811 static void tag_read_you(struct tagHeader &th, char minorVersion)
812 {
813     char buff[20];      // For birth date
814     int i,j;
815     char count_c;
816     short count_s;
817 
818     unmarshallString(th, you.your_name, 30);
819 
820     you.religion = unmarshallByte(th);
821     you.piety = unmarshallByte(th);
822     you.invis = unmarshallByte(th);
823     you.conf = unmarshallByte(th);
824     you.paralysis = unmarshallByte(th);
825     you.slow = unmarshallByte(th);
826     you.fire_shield = unmarshallByte(th);
827     you.rotting = unmarshallByte(th);
828     you.exhausted = unmarshallByte(th);
829     you.deaths_door = unmarshallByte(th);
830     your_sign = unmarshallByte(th);
831     your_colour = unmarshallByte(th);
832     you.pet_target = unmarshallByte(th);
833 
834     you.max_level = unmarshallByte(th);
835     you.where_are_you = unmarshallByte(th);
836     you.char_direction = unmarshallByte(th);
837     you.your_level = unmarshallByte(th);
838     you.is_undead = unmarshallByte(th);
839     you.special_wield = unmarshallByte(th);
840     you.berserker = unmarshallByte(th);
841     you.berserk_penalty = unmarshallByte(th);
842     you.level_type = unmarshallByte(th);
843     you.synch_time = unmarshallByte(th);
844     you.disease = unmarshallByte(th);
845     you.species = unmarshallByte(th);
846     you.hp = unmarshallShort(th);
847     you.haste = unmarshallByte(th);
848     you.might = unmarshallByte(th);
849     you.levitation = unmarshallByte(th);
850     you.poison = unmarshallByte(th);
851     you.hunger = unmarshallShort(th);
852 
853     // how many you.equip?
854     count_c = unmarshallByte(th);
855     for (i = 0; i < count_c; ++i)
856         you.equip[i] = unmarshallByte(th);
857 
858     you.magic_points = unmarshallByte(th);
859     you.max_magic_points = unmarshallByte(th);
860     you.strength = unmarshallByte(th);
861     you.intel = unmarshallByte(th);
862     you.dex = unmarshallByte(th);
863     you.confusing_touch = unmarshallByte(th);
864     you.sure_blade = unmarshallByte(th);
865     you.hit_points_regeneration = unmarshallByte(th);
866     you.magic_points_regeneration = unmarshallByte(th);
867 
868     you.hit_points_regeneration = unmarshallShort(th) / 100;
869     you.experience = unmarshallLong(th);
870     you.gold = unmarshallLong(th);
871 
872     you.char_class = unmarshallByte(th);
873     you.experience_level = unmarshallByte(th);
874     you.exp_available = unmarshallLong(th);
875 
876     /* max values */
877     you.max_strength = unmarshallByte(th);
878     you.max_intel = unmarshallByte(th);
879     you.max_dex = unmarshallByte(th);
880 
881     you.base_hp = unmarshallShort(th);
882     you.base_hp2 = unmarshallShort(th);
883     you.base_magic_points = unmarshallShort(th);
884     you.base_magic_points2 = unmarshallShort(th);
885 
886     you.x_pos = unmarshallShort(th);
887     you.y_pos = unmarshallShort(th);
888 
889     unmarshallString(th, you.class_name, 30);
890 
891     you.burden = unmarshallShort(th);
892 
893     // how many spells?
894     you.spell_no = 0;
895     count_c = unmarshallByte(th);
896     for (i = 0; i < count_c; ++i)
897     {
898         you.spells[i] = unmarshallByte(th);
899         if (you.spells[i] != SPELL_NO_SPELL)
900             you.spell_no++;
901     }
902 
903     if (minorVersion >= 2)
904     {
905         count_c = unmarshallByte(th);
906         for (i = 0; i < count_c; i++)
907             you.spell_letter_table[i] = unmarshallByte(th);
908 
909         count_c = unmarshallByte(th);
910         for (i = 0; i < count_c; i++)
911             you.ability_letter_table[i] = unmarshallShort(th);
912     }
913     else
914     {
915         for (i = 0; i < 52; i++)
916         {
917             you.spell_letter_table[i] = -1;
918             you.ability_letter_table[i] = ABIL_NON_ABILITY;
919         }
920 
921         for (i = 0; i < 25; i++)
922         {
923             if (you.spells[i] != SPELL_NO_SPELL)
924                 you.spell_letter_table[i] = i;
925         }
926 
927         if (you.religion != GOD_NO_GOD)
928             set_god_ability_slots();
929     }
930 
931     // how many skills?
932     count_c = unmarshallByte(th);
933     for (j = 0; j < count_c; ++j)
934     {
935         you.skills[j] = unmarshallByte(th);
936         you.practise_skill[j] = unmarshallByte(th);
937         you.skill_points[j] = unmarshallLong(th);
938 
939         if (minorVersion >= 2)
940             you.skill_order[j] = unmarshallByte(th);
941     }
942 
943     // initialize ordering when we don't read it in:
944     if (minorVersion < 2)
945         init_skill_order();
946 
947     // set up you.total_skill_points and you.skill_cost_level
948     calc_total_skill_points();
949 
950     // how many durations?
951     count_c = unmarshallByte(th);
952     for (j = 0; j < count_c; ++j)
953         you.duration[j] = unmarshallByte(th);
954 
955     // how many attributes?
956     count_c = unmarshallByte(th);
957     for (j = 0; j < count_c; ++j)
958         you.attribute[j] = unmarshallByte(th);
959 
960     // how many mutations/demon powers?
961     count_s = unmarshallShort(th);
962     for (j = 0; j < count_s; ++j)
963     {
964         you.mutation[j] = unmarshallByte(th);
965         you.demon_pow[j] = unmarshallByte(th);
966     }
967 
968     // how many penances?
969     count_c = unmarshallByte(th);
970     for (i = 0; i < count_c; i++)
971         you.penance[i] = unmarshallByte(th);
972 
973     if (minorVersion >= 2)
974     {
975         count_c = unmarshallByte(th);
976         for (i = 0; i < count_c; i++)
977             you.worshipped[i] = unmarshallByte(th);
978     }
979     else
980     {
981         for (i = 0; i < count_c; i++)
982             you.worshipped[i] = false;
983 
984         if (you.religion != GOD_NO_GOD)
985             you.worshipped[you.religion] = true;
986     }
987 
988     you.gift_timeout = unmarshallByte(th);
989     you.normal_vision = unmarshallByte(th);
990     you.current_vision = unmarshallByte(th);
991     you.hell_exit = unmarshallByte(th);
992 
993     // elapsed time
994     you.elapsed_time = (double)unmarshallFloat(th);
995 
996     if (minorVersion >= 1)
997     {
998         // wizard mode
999         you.wizard = (bool) unmarshallByte(th);
1000 
1001         // time of character creation
1002         unmarshallString( th, buff, 20 );
1003         you.birth_time = parse_date_string( buff );
1004     }
1005 
1006     if (minorVersion >= 2)
1007     {
1008         you.real_time = unmarshallLong(th);
1009         you.num_turns = unmarshallLong(th);
1010     }
1011     else
1012     {
1013         you.real_time = -1;
1014         you.num_turns = -1;
1015     }
1016 }
1017 
tag_convert_to_4_3_item(item_def & item)1018 static void tag_convert_to_4_3_item( item_def &item )
1019 {
1020     const unsigned char plus      = item.plus;
1021     const unsigned char plus2     = item.plus2;
1022     const unsigned char ident     = item.flags;
1023     const unsigned char special   = item.special;
1024 
1025     if (item.quantity <= 0)
1026         return;
1027 
1028     // First, convert ident into flags:
1029     item.flags = (ident == 3) ? ISFLAG_IDENT_MASK :
1030                  (ident >  0) ? ISFLAG_KNOW_CURSE
1031                               : 0;
1032 
1033     switch (item.base_type)
1034     {
1035     case OBJ_ARMOUR:
1036         if ((ident == 1 && special % 30 >= 25) || ident == 2)
1037             item.flags |= ISFLAG_KNOW_TYPE;
1038 
1039         // Convert special values
1040         item.special %= 30;
1041         if (item.special < 25)
1042         {
1043             if (item.sub_type == ARM_HELMET)
1044             {
1045                 item.plus2 = plus2 % 30;
1046                 set_helmet_desc( item, (special / 30) << 8 );
1047             }
1048             else
1049             {
1050                 switch (special / 30)
1051                 {
1052                 case DARM_EMBROIDERED_SHINY:
1053                     set_equip_desc( item, ISFLAG_EMBROIDERED_SHINY );
1054                     break;
1055                 case DARM_RUNED:
1056                     set_equip_desc( item, ISFLAG_RUNED );
1057                     break;
1058                 case DARM_GLOWING:
1059                     set_equip_desc( item, ISFLAG_GLOWING );
1060                     break;
1061                 case DARM_ELVEN:
1062                     set_equip_race( item, ISFLAG_ELVEN );
1063                     break;
1064                 case DARM_DWARVEN:
1065                     set_equip_race( item, ISFLAG_DWARVEN );
1066                     break;
1067                 case DARM_ORCISH:
1068                     set_equip_race( item, ISFLAG_ORCISH );
1069                     break;
1070                 default:
1071                     break;
1072                 }
1073             }
1074         }
1075         else if (item.special == 25)
1076         {
1077             item.flags |= ISFLAG_UNRANDART;
1078             item.special = 0;
1079         }
1080         else
1081         {
1082             item.flags |= ISFLAG_RANDART;
1083 
1084             // calc old seed
1085             item.special = item.base_type * special
1086                             + item.sub_type * (plus % 100)
1087                             + plus2 * 100;
1088         }
1089         break;
1090 
1091     case OBJ_WEAPONS:
1092         if ((ident == 1 && (special < 180 && special % 30 >= 25)) || ident == 2)
1093             item.flags |= ISFLAG_KNOW_TYPE;
1094 
1095         // Convert special values
1096         if (special < 181)  // don't mangle fixed artefacts
1097         {
1098             item.special %= 30;
1099             if (item.special < 25)
1100             {
1101                 switch (special / 30)
1102                 {
1103                 case DWPN_RUNED:
1104                     set_equip_desc( item, ISFLAG_RUNED );
1105                     break;
1106                 case DWPN_GLOWING:
1107                     set_equip_desc( item, ISFLAG_GLOWING );
1108                     break;
1109                 case DWPN_ORCISH:
1110                     set_equip_race( item, ISFLAG_ORCISH );
1111                     break;
1112                 case DWPN_ELVEN:
1113                     set_equip_race( item, ISFLAG_ELVEN );
1114                     break;
1115                 case DWPN_DWARVEN:
1116                     set_equip_race( item, ISFLAG_DWARVEN );
1117                     break;
1118                 default:
1119                     break;
1120                 }
1121             }
1122             else if (item.special == 25)
1123             {
1124                 item.flags |= ISFLAG_UNRANDART;
1125                 item.special = 0;
1126             }
1127             else
1128             {
1129                 item.flags |= ISFLAG_RANDART;
1130 
1131                 // calc old seed
1132                 item.special = item.base_type * special
1133                                 + item.sub_type * (plus % 100)
1134                                 + plus2 * 100;
1135             }
1136         }
1137         break;
1138 
1139     case OBJ_MISSILES:
1140         // Needles were moved into the bonus eggplant spot. -- bwr
1141         if (item.sub_type == 6)
1142             item.sub_type = MI_NEEDLE;
1143 
1144         if (ident == 2)
1145             item.flags |= ISFLAG_KNOW_TYPE;
1146 
1147         // Convert special values
1148         item.special %= 30;
1149         switch (special / 30)
1150         {
1151         case DAMMO_ORCISH:
1152             set_equip_race( item, ISFLAG_ORCISH );
1153             break;
1154         case DAMMO_ELVEN:
1155             set_equip_race( item, ISFLAG_ELVEN );
1156             break;
1157         case DAMMO_DWARVEN:
1158             set_equip_race( item, ISFLAG_DWARVEN );
1159             break;
1160         default:
1161             break;
1162         }
1163         break;
1164 
1165     case OBJ_WANDS:
1166         if (ident == 2)
1167             item.flags |= ISFLAG_KNOW_PLUSES;
1168         break;
1169 
1170     case OBJ_JEWELLERY:
1171         if (ident == 1 && (special == 200 || special == 201))
1172             item.flags |= ISFLAG_KNOW_TYPE;
1173         else if (ident == 2)
1174             item.flags |= (ISFLAG_KNOW_TYPE | ISFLAG_KNOW_PLUSES);
1175 
1176         if (special == 201)
1177         {
1178             item.flags |= ISFLAG_UNRANDART;
1179             item.special = 0;
1180         }
1181         else if (special == 200)
1182         {
1183             item.flags |= ISFLAG_RANDART;
1184 
1185             // calc old seed
1186             item.special = item.base_type * special
1187                             + item.sub_type * (plus % 100)
1188                             + plus2 * 100;
1189         }
1190         break;
1191 
1192     default:
1193         if (ident > 0)
1194             item.flags |= ISFLAG_KNOW_TYPE;
1195         break;
1196     }
1197 
1198 
1199     // Second, convert plus and plus2
1200     if (item.base_type == OBJ_WEAPONS
1201         || item.base_type == OBJ_MISSILES
1202         || item.base_type == OBJ_ARMOUR
1203         || item.base_type == OBJ_JEWELLERY)
1204     {
1205         item.plus = plus;
1206 
1207         // item is cursed:
1208         if (plus > 100)
1209         {
1210             item.plus -= 100;
1211             item.flags |= ISFLAG_CURSED;
1212         }
1213 
1214         // Weapons use both as pluses.
1215         // Non-artefact jewellery uses both as pluses.
1216         // Artefact jewellery has literal values for both pluses.
1217         // Armour and Missiles only use plus for their plus value.
1218         // Armour has literal usage of plus2 for sub-subtypes.
1219         if (item.base_type != OBJ_JEWELLERY)
1220         {
1221             item.plus -= 50;
1222 
1223             if (item.base_type == OBJ_WEAPONS)
1224                 item.plus2 -= 50;
1225         }
1226         else if (special != 200)
1227         {
1228             // regular jewellery & unrandarts -- unused pluses were 0s
1229             if (item.plus)
1230                 item.plus -= 50;
1231 
1232             if (item.plus2)
1233                 item.plus2 -= 50;
1234         }
1235         else if (special == 200)
1236         {
1237             // Randart jewellery used pluses only as seeds, right now
1238             // they're always zero (since random artefact rings avoid
1239             // base types with pluses).
1240             item.plus = 0;
1241             item.plus2 = 0;
1242         }
1243     }
1244 }
1245 
tag_read_you_items(struct tagHeader & th,char minorVersion)1246 static void tag_read_you_items(struct tagHeader &th, char minorVersion)
1247 {
1248     int i,j;
1249     char count_c, count_c2;
1250     short count_s;
1251 
1252     // how many inventory slots?
1253     count_c = unmarshallByte(th);
1254     for (i = 0; i < count_c; ++i)
1255     {
1256         if (minorVersion < 1)
1257         {
1258             you.inv[i].base_type = (unsigned char) unmarshallByte(th);
1259             you.inv[i].sub_type = (unsigned char) unmarshallByte(th);
1260             you.inv[i].plus = (unsigned char) unmarshallByte(th);
1261             you.inv[i].special = (unsigned char) unmarshallByte(th);
1262             you.inv[i].colour = (unsigned char) unmarshallByte(th);
1263             you.inv[i].flags = (unsigned char) unmarshallByte(th);
1264             you.inv[i].quantity = unmarshallShort(th);
1265             you.inv[i].plus2 = (unsigned char) unmarshallByte(th);
1266 
1267             tag_convert_to_4_3_item( you.inv[i] );
1268         }
1269         else
1270         {
1271             you.inv[i].base_type = (unsigned char) unmarshallByte(th);
1272             you.inv[i].sub_type = (unsigned char) unmarshallByte(th);
1273             you.inv[i].plus = unmarshallShort(th);
1274             you.inv[i].special = unmarshallLong(th);
1275             you.inv[i].colour = (unsigned char) unmarshallByte(th);
1276             you.inv[i].flags = (unsigned long) unmarshallLong(th);
1277             you.inv[i].quantity = unmarshallShort(th);
1278             you.inv[i].plus2 = unmarshallShort(th);
1279         }
1280 
1281         // these never need to be saved for items in the inventory -- bwr
1282         you.inv[i].x = -1;
1283         you.inv[i].y = -1;
1284         you.inv[i].link = i;
1285     }
1286 
1287     // item descrip for each type & subtype
1288     // how many types?
1289     count_c = unmarshallByte(th);
1290     // how many subtypes?
1291     count_c2 = unmarshallByte(th);
1292     for (i = 0; i < count_c; ++i)
1293     {
1294         for (j = 0; j < count_c2; ++j)
1295             you.item_description[i][j] = unmarshallByte(th);
1296     }
1297 
1298     // identification status
1299     // how many types?
1300     count_c = unmarshallByte(th);
1301     // how many subtypes?
1302     count_c2 = unmarshallByte(th);
1303 
1304     // argh.. this is awful.
1305     for (i = 0; i < count_c; ++i)
1306     {
1307         for (j = 0; j < count_c2; ++j)
1308         {
1309             char ch;
1310             ch = unmarshallByte(th);
1311 
1312             switch (i)
1313             {
1314                 case IDTYPE_WANDS:
1315                     set_ident_type(OBJ_WANDS, j, ch);
1316                     break;
1317                 case IDTYPE_SCROLLS:
1318                     set_ident_type(OBJ_SCROLLS, j, ch);
1319                     break;
1320                 case IDTYPE_JEWELLERY:
1321                     set_ident_type(OBJ_JEWELLERY, j, ch);
1322                     break;
1323                 case IDTYPE_POTIONS:
1324                     set_ident_type(OBJ_POTIONS, j, ch);
1325                     break;
1326             }
1327         }
1328     }
1329 
1330     // how many unique items?
1331     count_c = unmarshallByte(th);
1332     for (j = 0; j < count_c; ++j)
1333     {
1334         you.unique_items[j] = unmarshallByte(th);
1335         you.had_book[j] = unmarshallByte(th);
1336     }
1337 
1338     // how many unrandarts?
1339     count_s = unmarshallShort(th);
1340     for (j = 0; j < count_s; ++j)
1341         set_unrandart_exist(j, unmarshallBoolean(th));
1342 
1343     // # of unrandarts could certainly change.  If it does,
1344     // the new ones won't exist yet - zero them out.
1345     for (; j < NO_UNRANDARTS; j++)
1346         set_unrandart_exist(j, 0);
1347 }
1348 
tag_read_you_dungeon(struct tagHeader & th)1349 static void tag_read_you_dungeon(struct tagHeader &th)
1350 {
1351     int i,j;
1352     char count_c;
1353     short count_s;
1354 
1355     // how many unique creatures?
1356     count_c = unmarshallByte(th);
1357     for (j = 0; j < count_c; ++j)
1358         you.unique_creatures[j] = unmarshallByte(th);
1359 
1360     // how many branches?
1361     count_c = unmarshallByte(th);
1362     for (j = 0; j < count_c; ++j)
1363     {
1364         you.branch_stairs[j] = unmarshallByte(th);
1365         stair_level[j] = unmarshallByte(th);
1366     }
1367 
1368     // how many levels?
1369     count_s = unmarshallShort(th);
1370     for (i = 0; i < count_s; ++i)
1371     {
1372         for (j = 0; j < count_c; ++j)
1373         {
1374             altars_present[i][j] = unmarshallByte(th);
1375             feature[i][j] = unmarshallByte(th);
1376             tmp_file_pairs[i][j] = unmarshallBoolean(th);
1377         }
1378     }
1379 }
1380 
1381 // ------------------------------- level tags ---------------------------- //
1382 
tag_construct_level(struct tagHeader & th)1383 static void tag_construct_level(struct tagHeader &th)
1384 {
1385     int i;
1386     int count_x, count_y;
1387 
1388     marshallFloat(th, (float)you.elapsed_time);
1389 
1390     // map grids
1391     // how many X?
1392     marshallShort(th, GXM);
1393     // how many Y?
1394     marshallShort(th, GYM);
1395     for (count_x = 0; count_x < GXM; count_x++)
1396     {
1397         for (count_y = 0; count_y < GYM; count_y++)
1398         {
1399             marshallByte(th, grd[count_x][count_y]);
1400             marshallByte(th, env.map[count_x][count_y]);
1401             marshallByte(th, env.cgrid[count_x][count_y]);
1402         }
1403     }
1404 
1405     marshallShort(th, env.cloud_no);
1406 
1407     // how many clouds?
1408     marshallShort(th, MAX_CLOUDS);
1409     for (i = 0; i < MAX_CLOUDS; i++)
1410     {
1411         marshallByte(th, env.cloud[i].x);
1412         marshallByte(th, env.cloud[i].y);
1413         marshallByte(th, env.cloud[i].type);
1414         marshallShort(th, env.cloud[i].decay);
1415     }
1416 
1417     // how many shops?
1418     marshallByte(th, 5);
1419     for (i = 0; i < 5; i++)
1420     {
1421         marshallByte(th, env.shop[i].keeper_name[0]);
1422         marshallByte(th, env.shop[i].keeper_name[1]);
1423         marshallByte(th, env.shop[i].keeper_name[2]);
1424         marshallByte(th, env.shop[i].x);
1425         marshallByte(th, env.shop[i].y);
1426         marshallByte(th, env.shop[i].greed);
1427         marshallByte(th, env.shop[i].type);
1428         marshallByte(th, env.shop[i].level);
1429     }
1430 }
1431 
tag_construct_level_items(struct tagHeader & th)1432 static void tag_construct_level_items(struct tagHeader &th)
1433 {
1434     int i;
1435 
1436     // how many traps?
1437     marshallShort(th, MAX_TRAPS);
1438     for (i = 0; i < MAX_TRAPS; ++i)
1439     {
1440         marshallByte(th, env.trap[i].type);
1441         marshallByte(th, env.trap[i].x);
1442         marshallByte(th, env.trap[i].y);
1443     }
1444 
1445     // how many items?
1446     marshallShort(th, MAX_ITEMS);
1447     for (i = 0; i < MAX_ITEMS; ++i)
1448     {
1449         marshallByte(th, mitm[i].base_type);
1450         marshallByte(th, mitm[i].sub_type);
1451         marshallShort(th, mitm[i].plus);
1452         marshallShort(th, mitm[i].plus2);
1453         marshallLong(th, mitm[i].special);
1454         marshallShort(th, mitm[i].quantity);
1455 
1456         marshallByte(th, mitm[i].colour);
1457         marshallShort(th, mitm[i].x);
1458         marshallShort(th, mitm[i].y);
1459         marshallLong(th, mitm[i].flags);
1460 
1461         marshallShort(th, mitm[i].link);                //  unused
1462         marshallShort(th, igrd[mitm[i].x][mitm[i].y]);  //  unused
1463     }
1464 }
1465 
tag_construct_level_monsters(struct tagHeader & th)1466 static void tag_construct_level_monsters(struct tagHeader &th)
1467 {
1468     int i,j;
1469 
1470     // how many mons_alloc?
1471     marshallByte(th, 20);
1472     for (i = 0; i < 20; ++i)
1473         marshallShort(th, env.mons_alloc[i]);
1474 
1475     // how many monsters?
1476     marshallShort(th, MAX_MONSTERS);
1477     // how many monster enchantments?
1478     marshallByte(th, NUM_MON_ENCHANTS);
1479     // how many monster inventory slots?
1480     marshallByte(th, NUM_MONSTER_SLOTS);
1481 
1482     for (i = 0; i < MAX_MONSTERS; i++)
1483     {
1484         marshallByte(th, menv[i].armour_class);
1485         marshallByte(th, menv[i].evasion);
1486         marshallByte(th, menv[i].hit_dice);
1487         marshallByte(th, menv[i].speed);
1488         marshallByte(th, menv[i].speed_increment);
1489         marshallByte(th, menv[i].behaviour);
1490         marshallByte(th, menv[i].x);
1491         marshallByte(th, menv[i].y);
1492         marshallByte(th, menv[i].target_x);
1493         marshallByte(th, menv[i].target_y);
1494         marshallByte(th, menv[i].flags);
1495 
1496         for (j = 0; j < NUM_MON_ENCHANTS; j++)
1497             marshallByte(th, menv[i].enchantment[j]);
1498 
1499         marshallShort(th, menv[i].type);
1500         marshallShort(th, menv[i].hit_points);
1501         marshallShort(th, menv[i].max_hit_points);
1502         marshallShort(th, menv[i].number);
1503 
1504         for (j = 0; j < NUM_MONSTER_SLOTS; j++)
1505             marshallShort(th, menv[i].inv[j]);
1506     }
1507 }
1508 
tag_construct_level_attitude(struct tagHeader & th)1509 void tag_construct_level_attitude(struct tagHeader &th)
1510 {
1511     int i;
1512 
1513     // how many monsters?
1514     marshallShort(th, MAX_MONSTERS);
1515 
1516     for (i = 0; i < MAX_MONSTERS; i++)
1517     {
1518         marshallByte(th, menv[i].attitude);
1519         marshallShort(th, menv[i].foe);
1520     }
1521 }
1522 
1523 
tag_read_level(struct tagHeader & th,char minorVersion)1524 static void tag_read_level( struct tagHeader &th, char minorVersion )
1525 {
1526     int i,j;
1527     int gx, gy;
1528 
1529     env.elapsed_time = (double)unmarshallFloat(th);
1530 
1531     // map grids
1532     // how many X?
1533     gx = unmarshallShort(th);
1534     // how many Y?
1535     gy = unmarshallShort(th);
1536     for (i = 0; i < gx; i++)
1537     {
1538         for (j = 0; j < gy; j++)
1539         {
1540             grd[i][j] = unmarshallByte(th);
1541             env.map[i][j] = unmarshallByte(th);
1542             if (env.map[i][j] == 201)       // what is this??
1543                 env.map[i][j] = 239;
1544 
1545             mgrd[i][j] = NON_MONSTER;
1546             env.cgrid[i][j] = unmarshallByte(th);
1547 
1548             if (minorVersion < 3)
1549             {
1550                 // increased number of clouds to 100 in 4.3
1551                 if (env.cgrid[i][j] > 30)
1552                     env.cgrid[i][j] = 101;
1553             }
1554         }
1555     }
1556 
1557     env.cloud_no = unmarshallShort(th);
1558 
1559     // how many clouds?
1560     gx = unmarshallShort(th);
1561     for (i = 0; i < gx; i++)
1562     {
1563         env.cloud[i].x = unmarshallByte(th);
1564         env.cloud[i].y = unmarshallByte(th);
1565         env.cloud[i].type = unmarshallByte(th);
1566         env.cloud[i].decay = unmarshallShort(th);
1567     }
1568 
1569     // how many shops?
1570     gx = unmarshallByte(th);
1571     for (i = 0; i < gx; i++)
1572     {
1573         env.shop[i].keeper_name[0] = unmarshallByte(th);
1574         env.shop[i].keeper_name[1] = unmarshallByte(th);
1575         env.shop[i].keeper_name[2] = unmarshallByte(th);
1576         env.shop[i].x = unmarshallByte(th);
1577         env.shop[i].y = unmarshallByte(th);
1578         env.shop[i].greed = unmarshallByte(th);
1579         env.shop[i].type = unmarshallByte(th);
1580         env.shop[i].level = unmarshallByte(th);
1581     }
1582 }
1583 
tag_read_level_items(struct tagHeader & th,char minorVersion)1584 static void tag_read_level_items(struct tagHeader &th, char minorVersion)
1585 {
1586     int i;
1587     int count;
1588 
1589     // how many traps?
1590     count = unmarshallShort(th);
1591     for (i = 0; i < count; ++i)
1592     {
1593         env.trap[i].type = unmarshallByte(th);
1594         env.trap[i].x = unmarshallByte(th);
1595         env.trap[i].y = unmarshallByte(th);
1596     }
1597 
1598     // how many items?
1599     count = unmarshallShort(th);
1600     for (i = 0; i < count; ++i)
1601     {
1602         if (minorVersion < 3)
1603         {
1604             mitm[i].base_type = (unsigned char) unmarshallByte(th);
1605             mitm[i].sub_type = (unsigned char) unmarshallByte(th);
1606             mitm[i].plus = (unsigned char) unmarshallByte(th);
1607             mitm[i].plus2 = (unsigned char) unmarshallByte(th);
1608             mitm[i].special = (unsigned char) unmarshallByte(th);
1609             mitm[i].quantity = unmarshallLong(th);
1610             mitm[i].colour = (unsigned char) unmarshallByte(th);
1611             mitm[i].x = (unsigned char) unmarshallByte(th);
1612             mitm[i].y = (unsigned char) unmarshallByte(th);
1613             mitm[i].flags = (unsigned char) unmarshallByte(th);
1614 
1615             tag_convert_to_4_3_item( mitm[i] );
1616         }
1617         else
1618         {
1619             mitm[i].base_type = (unsigned char) unmarshallByte(th);
1620             mitm[i].sub_type = (unsigned char) unmarshallByte(th);
1621             mitm[i].plus = unmarshallShort(th);
1622             mitm[i].plus2 = unmarshallShort(th);
1623             mitm[i].special = unmarshallLong(th);
1624             mitm[i].quantity = unmarshallShort(th);
1625             mitm[i].colour = (unsigned char) unmarshallByte(th);
1626             mitm[i].x = unmarshallShort(th);
1627             mitm[i].y = unmarshallShort(th);
1628             mitm[i].flags = (unsigned long) unmarshallLong(th);
1629         }
1630 
1631         // pre 4.2 files had monster items stacked at (2,2) -- moved to (0,0)
1632         if (minorVersion < 2 && mitm[i].x == 2 && mitm[i].y == 2)
1633         {
1634             mitm[i].x = 0;
1635             mitm[i].y = 0;
1636         }
1637 
1638         unmarshallShort(th);  // mitm[].link -- unused
1639         unmarshallShort(th);  // igrd[mitm[i].x][mitm[i].y] -- unused
1640     }
1641 }
1642 
tag_read_level_monsters(struct tagHeader & th,char minorVersion)1643 static void tag_read_level_monsters(struct tagHeader &th, char minorVersion)
1644 {
1645     int i,j;
1646     int count, ecount, icount;
1647 
1648     // how many mons_alloc?
1649     count = unmarshallByte(th);
1650     for (i = 0; i < count; ++i)
1651         env.mons_alloc[i] = unmarshallShort(th);
1652 
1653     // how many monsters?
1654     count = unmarshallShort(th);
1655     // how many monster enchantments?
1656     ecount = unmarshallByte(th);
1657     // how many monster inventory slots?
1658     icount = unmarshallByte(th);
1659 
1660     for (i = 0; i < count; i++)
1661     {
1662         menv[i].armour_class = unmarshallByte(th);
1663         menv[i].evasion = unmarshallByte(th);
1664         menv[i].hit_dice = unmarshallByte(th);
1665         menv[i].speed = unmarshallByte(th);
1666         menv[i].speed_increment = unmarshallByte(th);
1667         menv[i].behaviour = unmarshallByte(th);
1668         menv[i].x = unmarshallByte(th);
1669         menv[i].y = unmarshallByte(th);
1670         menv[i].target_x = unmarshallByte(th);
1671         menv[i].target_y = unmarshallByte(th);
1672         menv[i].flags = unmarshallByte(th);
1673 
1674         // VERSION NOTICE:  for pre 4.2 files,  flags was either 0
1675         // or 1.  Now,  we can transfer ENCH_CREATED_FRIENDLY over
1676         // from the enchantments array to flags.
1677         // Also need to take care of ENCH_FRIEND_ABJ_xx flags
1678 
1679         for (j = 0; j < ecount; j++)
1680             menv[i].enchantment[j] = unmarshallByte(th);
1681 
1682         if (minorVersion < 2)
1683         {
1684             menv[i].flags = 0;
1685             for(j=0; j<NUM_MON_ENCHANTS; j++)
1686             {
1687                 if (j>=ecount)
1688                     menv[i].enchantment[j] = ENCH_NONE;
1689                 else
1690                 {
1691                     if (menv[i].enchantment[j] == 71) // old ENCH_CREATED_FRIENDLY
1692                     {
1693                         menv[i].enchantment[j] = ENCH_NONE;
1694                         menv[i].flags |= MF_CREATED_FRIENDLY;
1695                     }
1696                     if (menv[i].enchantment[j] >= 65 // old ENCH_FRIEND_ABJ_I
1697                       && menv[i].enchantment[j] <= 70) // old ENCH_FRIEND_ABJ_VI
1698                     {
1699                         menv[i].enchantment[j] -= (65 - ENCH_ABJ_I);
1700                         menv[i].flags |= MF_CREATED_FRIENDLY;
1701                     }
1702                 }
1703             }
1704         } // end  minorversion < 2
1705 
1706         menv[i].type = unmarshallShort(th);
1707         menv[i].hit_points = unmarshallShort(th);
1708         menv[i].max_hit_points = unmarshallShort(th);
1709         menv[i].number = unmarshallShort(th);
1710 
1711         for (j = 0; j < icount; j++)
1712             menv[i].inv[j] = unmarshallShort(th);
1713 
1714         // place monster
1715         if (menv[i].type != -1)
1716             mgrd[menv[i].x][menv[i].y] = i;
1717     }
1718 }
1719 
tag_read_level_attitude(struct tagHeader & th)1720 void tag_read_level_attitude(struct tagHeader &th)
1721 {
1722     int i, count;
1723 
1724     // how many monsters?
1725     count = unmarshallShort(th);
1726 
1727     for (i = 0; i < count; i++)
1728     {
1729         menv[i].attitude = unmarshallByte(th);
1730         menv[i].foe = unmarshallShort(th);
1731     }
1732 }
1733 
tag_missing_level_attitude()1734 void tag_missing_level_attitude()
1735 {
1736     // we don't really have to do a lot here.
1737     // just set foe to MHITNOT;  they'll pick up
1738     // a foe first time through handle_monster() if
1739     // there's one around.
1740 
1741     // as for attitude,  a couple simple checks
1742     // can be used to determine friendly/neutral/
1743     // hostile.
1744     int i;
1745     bool isFriendly;
1746     unsigned int new_beh = BEH_WANDER;
1747 
1748     for(i=0; i<MAX_MONSTERS; i++)
1749     {
1750         // only do actual monsters
1751         if (menv[i].type < 0)
1752             continue;
1753 
1754         isFriendly = testbits(menv[i].flags, MF_CREATED_FRIENDLY);
1755 
1756         menv[i].foe = MHITNOT;
1757 
1758         switch(menv[i].behaviour)
1759         {
1760             case 0:         // old BEH_SLEEP
1761                 new_beh = BEH_SLEEP;    // don't wake sleepers
1762                 break;
1763             case 3:         // old BEH_FLEE
1764             case 10:        // old BEH_FLEE_FRIEND
1765                 new_beh = BEH_FLEE;
1766                 break;
1767             case 1:         // old BEH_CHASING_I
1768             case 6:         // old BEH_FIGHT
1769                 new_beh = BEH_SEEK;
1770                 break;
1771             case 7:         // old BEH_ENSLAVED
1772                 if (!mons_has_ench(&menv[i], ENCH_CHARM))
1773                     isFriendly = true;
1774                 break;
1775             default:
1776                 break;
1777         }
1778 
1779         menv[i].attitude = (isFriendly)?ATT_FRIENDLY : ATT_HOSTILE;
1780         menv[i].behaviour = new_beh;
1781         menv[i].foe_memory = 0;
1782     }
1783 }
1784 
1785 
1786 // ------------------------------- ghost tags ---------------------------- //
1787 
tag_construct_ghost(struct tagHeader & th)1788 static void tag_construct_ghost(struct tagHeader &th)
1789 {
1790     int i;
1791 
1792     marshallString(th, ghost.name, 20);
1793 
1794     // how many ghost values?
1795     marshallByte(th, 20);
1796 
1797     for (i = 0; i < 20; i++)
1798         marshallShort( th, ghost.values[i] );
1799 }
1800 
tag_read_ghost(struct tagHeader & th,char minorVersion)1801 static void tag_read_ghost(struct tagHeader &th, char minorVersion)
1802 {
1803     int i, count_c;
1804 
1805     snprintf( info, INFO_SIZE, "minor version = %d", minorVersion );
1806 
1807     unmarshallString(th, ghost.name, 20);
1808 
1809     // how many ghost values?
1810     count_c = unmarshallByte(th);
1811 
1812     for (i = 0; i < count_c; i++)
1813     {
1814         // for version 4.4 we moved from unsigned char to shorts -- bwr
1815         if (minorVersion < 4)
1816             ghost.values[i] = unmarshallByte(th);
1817         else
1818             ghost.values[i] = unmarshallShort(th);
1819     }
1820 
1821     if (minorVersion < 4)
1822     {
1823         // Getting rid 9of hopefulling the last) of this silliness -- bwr
1824         if (ghost.values[ GVAL_RES_FIRE ] >= 97)
1825             ghost.values[ GVAL_RES_FIRE ] -= 100;
1826 
1827         if (ghost.values[ GVAL_RES_COLD ] >= 97)
1828             ghost.values[ GVAL_RES_COLD ] -= 100;
1829     }
1830 }
1831 
1832 // ----------------------------------------------------------------------- //
1833