diff options
Diffstat (limited to 'stone_soup/crawl-ref/source/tags.cc')
-rw-r--r-- | stone_soup/crawl-ref/source/tags.cc | 1894 |
1 files changed, 0 insertions, 1894 deletions
diff --git a/stone_soup/crawl-ref/source/tags.cc b/stone_soup/crawl-ref/source/tags.cc deleted file mode 100644 index 25e4382274..0000000000 --- a/stone_soup/crawl-ref/source/tags.cc +++ /dev/null @@ -1,1894 +0,0 @@ -/* - * File: tags.cc - * Summary: Auxilary functions to make savefile versioning simpler. - * Written by: Gordon Lipford - * - * Modified for Crawl Reference by $Author$ on $Date$ - * - * Change History (most recent first): - * - * <2> 16 Mar 2001 GDL Added TAG_LEVEL_ATTITUDE - * <1> 27 Jan 2001 GDL Created - */ - -/* ------------------------- how tags work ---------------------------------- - -1. Tag types are enumerated in enum.h, from TAG_VERSION (more a placeholder - than anything else, it is not actually saved as a tag) to TAG_XXX. NUM_TAGS - is equal to the actual number of defined tags. - -2. Tags are created with tag_construct(), which forwards the construction - request appropriately. tag_write() is then used to write the tag to an - output stream. - -3. Tags are parsed with tag_read(), which tries to read a tag header and then - forwards the request appropriately, returning the ID of the tag it found, - or zero if no tag was found. - -4. In order to know which tags are used by a particular file type, a client - calls tag_set_expected( fileType ), which sets up an array of chars. - Within the array, a value of 1 means the tag is expected; -1 means that - the tag is not expected. A client can then set values in this array to - anything other than 1 to indicate a successful tag_read() of that tag. - -5. A case should be provided in tag_missing() for any tag which might be - missing from a tagged save file. For example, if a developer adds - TAG_YOU_NEW_STUFF to the player save file, he would have to provide a - case in tag_missing() for this tag since it might not be there in - earlier savefiles. The tags defined with the original tag system (and - so not needing cases in tag_missing()) are as follows: - - TAG_YOU = 1, // 'you' structure - TAG_YOU_ITEMS, // your items - TAG_YOU_DUNGEON, // dungeon specs (stairs, branches, features) - TAG_LEVEL, // various grids & clouds - TAG_LEVEL_ITEMS, // items/traps - TAG_LEVEL_MONSTERS, // monsters - TAG_GHOST, // ghost - -6. The marshalling and unmarshalling of data is done in network order and - is meant to keep savefiles cross-platform. They are non-ascii - always - FTP in binary mode. Note also that the marshalling sizes are 1,2, and 4 - for byte, short, and long - assuming that 'int' would have been - insufficient on 16 bit systems (and that Crawl otherwise lacks - system-indepedent data types). - -*/ - -#include <stdio.h> -#include <string.h> // for memcpy - -#ifdef UNIX -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#endif - -#ifdef USE_EMX -#include <sys/types.h> -#include <fcntl.h> -#include <unistd.h> -#endif - -#ifdef OS9 -#include <stat.h> -#else -#include <sys/stat.h> -#endif - -#include "AppHdr.h" - -#include "abl-show.h" -#include "enum.h" -#include "externs.h" -#include "files.h" -#include "itemname.h" -#include "itemprop.h" -#include "monstuff.h" -#include "mon-util.h" -#include "randart.h" -#include "skills.h" -#include "skills2.h" -#include "stuff.h" -#include "tags.h" - -// THE BIG IMPORTANT TAG CONSTRUCTION/PARSE BUFFER -static char *tagBuffer = NULL; - -// These three are defined in overmap.cc -extern FixedArray < unsigned char, MAX_LEVELS, MAX_BRANCHES > altars_present; -extern FixedVector < char, MAX_BRANCHES > stair_level; -extern FixedArray < unsigned char, MAX_LEVELS, MAX_BRANCHES > feature; - -extern unsigned char your_sign; /* these two are defined in view.cc */ -extern unsigned char your_colour; - -// temp file pairs used for file level cleanup -FixedArray < bool, MAX_LEVELS, MAX_BRANCHES > tmp_file_pairs; - - -// static helpers -static void tag_construct_you(struct tagHeader &th); -static void tag_construct_you_items(struct tagHeader &th); -static void tag_construct_you_dungeon(struct tagHeader &th); -static void tag_read_you(struct tagHeader &th, char minorVersion); -static void tag_read_you_items(struct tagHeader &th, char minorVersion); -static void tag_read_you_dungeon(struct tagHeader &th); - -static void tag_construct_level(struct tagHeader &th); -static void tag_construct_level_items(struct tagHeader &th); -static void tag_construct_level_monsters(struct tagHeader &th); -static void tag_construct_level_attitude(struct tagHeader &th); -static void tag_read_level(struct tagHeader &th, char minorVersion); -static void tag_read_level_items(struct tagHeader &th, char minorVersion); -static void tag_read_level_monsters(struct tagHeader &th, char minorVersion); -static void tag_read_level_attitude(struct tagHeader &th); -static void tag_missing_level_attitude(); - -static void tag_construct_ghost(struct tagHeader &th); -static void tag_read_ghost(struct tagHeader &th, char minorVersion); - -// provide a wrapper for file writing, just in case. -int write2(FILE * file, const char *buffer, unsigned int count) -{ - return fwrite(buffer, 1, count, file); -} - -// provide a wrapper for file reading, just in case. -int read2(FILE * file, char *buffer, unsigned int count) -{ - return fread(buffer, 1, count, file); -} - -void marshallByte(struct tagHeader &th, char data) -{ - tagBuffer[th.offset] = data; - th.offset += 1; -} - -char unmarshallByte(struct tagHeader &th) -{ - char data = tagBuffer[th.offset]; - th.offset += 1; - return data; -} - -// marshall 2 byte short in network order -void marshallShort(struct tagHeader &th, short data) -{ - char b2 = (char)(data & 0x00FF); - char b1 = (char)((data & 0xFF00) >> 8); - - tagBuffer[th.offset] = b1; - tagBuffer[th.offset + 1] = b2; - - th.offset += 2; -} - -// unmarshall 2 byte short in network order -short unmarshallShort(struct tagHeader &th) -{ - short b1 = tagBuffer[th.offset]; - short b2 = tagBuffer[th.offset + 1]; - - short data = (b1 << 8) | (b2 & 0x00FF); - - th.offset += 2; - return data; -} - -// marshall 4 byte int in network order -void marshallLong(struct tagHeader &th, long data) -{ - char b4 = (char) (data & 0x000000FF); - char b3 = (char)((data & 0x0000FF00) >> 8); - char b2 = (char)((data & 0x00FF0000) >> 16); - char b1 = (char)((data & 0xFF000000) >> 24); - - tagBuffer[th.offset] = b1; - tagBuffer[th.offset + 1] = b2; - tagBuffer[th.offset + 2] = b3; - tagBuffer[th.offset + 3] = b4; - - th.offset += 4; -} - -// unmarshall 4 byte int in network order -long unmarshallLong(struct tagHeader &th) -{ - long b1 = tagBuffer[th.offset]; - long b2 = tagBuffer[th.offset + 1]; - long b3 = tagBuffer[th.offset + 2]; - long b4 = tagBuffer[th.offset + 3]; - - long data = (b1 << 24) | ((b2 & 0x000000FF) << 16); - data |= ((b3 & 0x000000FF) << 8) | (b4 & 0x000000FF); - - th.offset += 4; - return data; -} - -// single precision float -- marshall in network order. -void marshallFloat(struct tagHeader &th, float data) -{ - long intBits = *((long *)(&data)); - marshallLong(th, intBits); -} - -// single precision float -- unmarshall in network order. -float unmarshallFloat(struct tagHeader &th) -{ - long intBits = unmarshallLong(th); - - return *((float *)(&intBits)); -} - -// string -- marshall length & string data -void marshallString(struct tagHeader &th, char *data, int maxSize) -{ - // allow for very long strings. - short len = strlen(data); - if (maxSize > 0 && len > maxSize) - len = maxSize; - marshallShort(th, len); - - // put in the actual string -- we'll null terminate on - // unmarshall. - memcpy(&tagBuffer[th.offset], data, len); - - th.offset += len; -} - -// string -- unmarshall length & string data -void unmarshallString(struct tagHeader &th, char *data, int maxSize) -{ - // get length - short len = unmarshallShort(th); - int copylen = len; - if (len > maxSize && maxSize > 0) - copylen = maxSize; - - // read the actual string and null terminate - memcpy(data, &tagBuffer[th.offset], copylen); - data[copylen] = '\0'; - - th.offset += len; -} - -// boolean (to avoid system-dependant bool implementations) -void marshallBoolean(struct tagHeader &th, bool data) -{ - char charRep = 0; // for false - if (data) - charRep = 1; - - tagBuffer[th.offset] = charRep; - th.offset += 1; -} - -// boolean (to avoid system-dependant bool implementations) -bool unmarshallBoolean(struct tagHeader &th) -{ - bool data; - - if (tagBuffer[th.offset] == 1) - data = true; - else - data = false; - - th.offset += 1; - return data; -} - -// Saving the date as a string so we're not reliant on a particular epoch. -void make_date_string( time_t in_date, char buff[20] ) -{ - if (in_date <= 0) - { - buff[0] = '\0'; - return; - } - - - struct tm *date = localtime( &in_date ); - - snprintf( buff, 20, - "%4d%02d%02d%02d%02d%02d%s", - date->tm_year + 1900, date->tm_mon, date->tm_mday, - date->tm_hour, date->tm_min, date->tm_sec, - ((date->tm_isdst > 0) ? "D" : "S") ); -} - -static int get_val_from_string( const char *ptr, int len ) -{ - int ret = 0; - int pow = 1; - - for (const char *chr = ptr + len - 1; chr >= ptr; chr--) - { - ret += (*chr - '0') * pow; - pow *= 10; - } - - return (ret); -} - -time_t parse_date_string( char buff[20] ) -{ - struct tm date; - - date.tm_year = get_val_from_string( &buff[0], 4 ) - 1900; - date.tm_mon = get_val_from_string( &buff[4], 2 ); - date.tm_mday = get_val_from_string( &buff[6], 2 ); - date.tm_hour = get_val_from_string( &buff[8], 2 ); - date.tm_min = get_val_from_string( &buff[10], 2 ); - date.tm_sec = get_val_from_string( &buff[12], 2 ); - - date.tm_isdst = (buff[14] == 'D'); - - return (mktime( &date )); -} - -// PUBLIC TAG FUNCTIONS -void tag_init(long largest_tag) -{ - if (tagBuffer != NULL) - return; - - tagBuffer = (char *)malloc(largest_tag); -} - -void tag_construct(struct tagHeader &th, int tagID) -{ - th.offset = 0; - th.tagID = tagID; - - switch(tagID) - { - case TAG_YOU: - tag_construct_you(th); - break; - case TAG_YOU_ITEMS: - tag_construct_you_items(th); - break; - case TAG_YOU_DUNGEON: - tag_construct_you_dungeon(th); - break; - case TAG_LEVEL: - tag_construct_level(th); - break; - case TAG_LEVEL_ITEMS: - tag_construct_level_items(th); - break; - case TAG_LEVEL_MONSTERS: - tag_construct_level_monsters(th); - break; - case TAG_LEVEL_ATTITUDE: - tag_construct_level_attitude(th); - break; - case TAG_GHOST: - tag_construct_ghost(th); - break; - default: - // I don't know how to make that! - break; - } -} - -void tag_write(struct tagHeader &th, FILE *saveFile) -{ - const int tagHdrSize = 6; - int tagSize=0; - - char swap[tagHdrSize]; - - // make sure there is some data to write! - if (th.offset == 0) - return; - - // special case: TAG_VERSION. Skip tag header. - if (th.tagID != TAG_VERSION) - { - // swap out first few bytes - memcpy(swap, tagBuffer, tagHdrSize); - - // save tag size - tagSize = th.offset; - - // swap in the header - th.offset = 0; - marshallShort(th, th.tagID); - marshallLong(th, tagSize); - - // write header - write2(saveFile, tagBuffer, th.offset); - - // swap real data back in - memcpy(tagBuffer, swap, tagHdrSize); - - // reset tag size - th.offset = tagSize; - } - - // write tag data - write2(saveFile, tagBuffer, th.offset); - return; -} - -// minorVersion is available for any sub-readers that need it -// (like TAG_LEVEL_MONSTERS) -int tag_read(FILE *fp, char minorVersion) -{ - const int tagHdrSize = 6; - struct tagHeader hdr, th; - th.offset = 0; - - // read tag header - if (read2(fp, tagBuffer, tagHdrSize) != tagHdrSize) - return 0; - - // unmarshall tag type and length (not including header) - hdr.tagID = unmarshallShort(th); - hdr.offset = unmarshallLong(th); - - // sanity check - if (hdr.tagID <= 0 || hdr.offset <= 0) - return 0; - - // now reset th and read actual data - th.offset = 0; - if (read2(fp, tagBuffer, hdr.offset) != hdr.offset) - return 0; - - // ok, we have data now. - switch(hdr.tagID) - { - case TAG_YOU: - tag_read_you(th, minorVersion); - break; - case TAG_YOU_ITEMS: - tag_read_you_items(th, minorVersion); - break; - case TAG_YOU_DUNGEON: - tag_read_you_dungeon(th); - break; - case TAG_LEVEL: - tag_read_level(th, minorVersion); - break; - case TAG_LEVEL_ITEMS: - tag_read_level_items(th, minorVersion); - break; - case TAG_LEVEL_MONSTERS: - tag_read_level_monsters(th, minorVersion); - break; - case TAG_LEVEL_ATTITUDE: - tag_read_level_attitude(th); - break; - case TAG_GHOST: - tag_read_ghost(th, minorVersion); - break; - default: - // I don't know how to read that! - return 0; - } - - return hdr.tagID; -} - - -// older savefiles might want to call this to get a tag -// properly initialized if it wasn't part of the savefile. -// For now, none are supported. - -// This function will be called AFTER all other tags for -// the savefile are read, so everything that can be -// initialized should have been by now. - -// minorVersion is available for any child functions that need -// it (currently none) -void tag_missing(int tag, char minorVersion) -{ - UNUSED( minorVersion ); - - switch(tag) - { - case TAG_LEVEL_ATTITUDE: - tag_missing_level_attitude(); - break; - default: - perror("Tag %d is missing; file is likely corrupt."); - end(-1); - } -} - -// utility -void tag_set_expected(char tags[], int fileType) -{ - int i; - - for(i=0; i<NUM_TAGS; i++) - { - tags[i] = -1; - switch(fileType) - { - case TAGTYPE_PLAYER: - if (i >= TAG_YOU && i <=TAG_YOU_DUNGEON) - tags[i] = 1; - break; - case TAGTYPE_LEVEL: - if (i >= TAG_LEVEL && i <= TAG_LEVEL_ATTITUDE) - tags[i] = 1; - break; - case TAGTYPE_GHOST: - if (i == TAG_GHOST) - tags[i] = 1; - default: - // I don't know what kind of file that is! - break; - } - } -} - -// NEVER _MODIFY_ THE CONSTRUCT/READ FUNCTIONS, EVER. THAT IS THE WHOLE POINT -// OF USING TAGS. Apologies for the screaming. - -// Note anyway that the formats are somewhat flexible; you could change map -// size, the # of slots in player inventory, etc. Constants like GXM, -// NUM_EQUIP, and NUM_DURATIONS are saved, so the appropriate amount will -// be restored even if a later version increases these constants. - -// --------------------------- player tags (foo.sav) -------------------- // -static void tag_construct_you(struct tagHeader &th) -{ - char buff[20]; // used for date string - int i,j; - - marshallString(th, you.your_name, 30); - - marshallByte(th,you.religion); - marshallByte(th,you.piety); - marshallByte(th,you.invis); - marshallByte(th,you.conf); - marshallByte(th,you.paralysis); - marshallByte(th,you.slow); - marshallByte(th,you.fire_shield); - marshallByte(th,you.rotting); - marshallByte(th,you.exhausted); - marshallByte(th,you.deaths_door); - marshallByte(th,your_sign); - marshallByte(th,your_colour); - marshallByte(th,you.pet_target); - - marshallByte(th,you.max_level); - marshallByte(th,you.where_are_you); - marshallByte(th,you.char_direction); - marshallByte(th,you.your_level); - marshallByte(th,you.is_undead); - marshallByte(th,you.special_wield); - marshallByte(th,you.berserker); - marshallByte(th,you.berserk_penalty); - marshallByte(th,you.level_type); - marshallByte(th,you.synch_time); - marshallByte(th,you.disease); - marshallByte(th,you.species); - - marshallShort(th, you.hp); - - if (you.haste > 215) - you.haste = 215; - - marshallByte(th,you.haste); - - if (you.might > 215) - you.might = 215; - - marshallByte(th,you.might); - - if (you.levitation > 215) - you.levitation = 215; - - marshallByte(th,you.levitation); - - if (you.poison > 215) - you.poison = 215; - - marshallByte(th,you.poison); - - marshallShort(th, you.hunger); - - // how many you.equip? - marshallByte(th, NUM_EQUIP); - for (i = 0; i < NUM_EQUIP; ++i) - marshallByte(th,you.equip[i]); - - marshallByte(th,you.magic_points); - marshallByte(th,you.max_magic_points); - marshallByte(th,you.strength); - marshallByte(th,you.intel); - marshallByte(th,you.dex); - marshallByte(th,you.confusing_touch); - marshallByte(th,you.sure_blade); - marshallByte(th,you.hit_points_regeneration); - marshallByte(th,you.magic_points_regeneration); - - marshallShort(th, you.hit_points_regeneration * 100); - marshallLong(th, you.experience); - marshallLong(th, you.gold); - - marshallByte(th,you.char_class); - marshallByte(th,you.experience_level); - marshallLong(th, you.exp_available); - - /* max values */ - marshallByte(th,you.max_strength); - marshallByte(th,you.max_intel); - marshallByte(th,you.max_dex); - - marshallShort(th, you.base_hp); - marshallShort(th, you.base_hp2); - marshallShort(th, you.base_magic_points); - marshallShort(th, you.base_magic_points2); - - marshallShort(th, you.x_pos); - marshallShort(th, you.y_pos); - - marshallString(th, you.class_name, 30); - - marshallShort(th, you.burden); - - // how many spells? - marshallByte(th, 25); - for (i = 0; i < 25; ++i) - marshallByte(th, you.spells[i]); - - marshallByte(th, 52); - for (i = 0; i < 52; i++) - marshallByte( th, you.spell_letter_table[i] ); - - marshallByte(th, 52); - for (i = 0; i < 52; i++) - marshallShort( th, you.ability_letter_table[i] ); - - // how many skills? - marshallByte(th, 50); - for (j = 0; j < 50; ++j) - { - marshallByte(th,you.skills[j]); /* skills! */ - marshallByte(th,you.practise_skill[j]); /* skills! */ - marshallLong(th,you.skill_points[j]); - marshallByte(th,you.skill_order[j]); /* skills ordering */ - } - - // how many durations? - marshallByte(th, NUM_DURATIONS); - for (j = 0; j < NUM_DURATIONS; ++j) - marshallByte(th,you.duration[j]); - - // how many attributes? - marshallByte(th, 30); - for (j = 0; j < 30; ++j) - marshallByte(th,you.attribute[j]); - - // how many mutations/demon powers? - marshallShort(th, 100); - for (j = 0; j < 100; ++j) - { - marshallByte(th,you.mutation[j]); - marshallByte(th,you.demon_pow[j]); - } - - // how many penances? - marshallByte(th, MAX_NUM_GODS); - for (i = 0; i < MAX_NUM_GODS; i++) - marshallByte(th, you.penance[i]); - - // which gods have been worshipped by this character? - marshallByte(th, MAX_NUM_GODS); - for (i = 0; i < MAX_NUM_GODS; i++) - marshallByte(th, you.worshipped[i]); - - // what is the extent of divine generosity? - for (i = 0; i < MAX_NUM_GODS; i++) - marshallShort(th, you.num_gifts[i]); - - marshallByte(th, you.gift_timeout); - marshallByte(th, you.normal_vision); - marshallByte(th, you.current_vision); - marshallByte(th, you.hell_exit); - - // elapsed time - marshallFloat(th, (float)you.elapsed_time); - - // wizard mode used - marshallByte(th, you.wizard); - - // time of game start - make_date_string( you.birth_time, buff ); - marshallString(th, buff, 20); - - // real_time == -1 means game was started before this feature - if (you.real_time != -1) - { - const time_t now = time(NULL); - you.real_time += (now - you.start_time); - - // Reset start_time now that real_time is being saved out... - // this may just be a level save. - you.start_time = now; - } - - marshallLong( th, you.real_time ); - marshallLong( th, you.num_turns ); - - // you.magic_contamination 05/03/05 - marshallShort(th, you.magic_contamination); -} - -static void tag_construct_you_items(struct tagHeader &th) -{ - int i,j; - - // how many inventory slots? - marshallByte(th, ENDOFPACK); - for (i = 0; i < ENDOFPACK; ++i) - { - marshallByte(th,you.inv[i].base_type); - marshallByte(th,you.inv[i].sub_type); - marshallShort(th,you.inv[i].plus); - marshallLong(th,you.inv[i].special); - marshallByte(th,you.inv[i].colour); - marshallLong(th,you.inv[i].flags); - marshallShort(th,you.inv[i].quantity); - marshallShort(th,you.inv[i].plus2); - marshallShort(th, you.inv[i].orig_place); - marshallShort(th, you.inv[i].orig_monnum); - } - - // item descrip for each type & subtype - // how many types? - marshallByte(th, 5); - // how many subtypes? - marshallByte(th, 50); - for (i = 0; i < 5; ++i) - { - for (j = 0; j < 50; ++j) - marshallByte(th, you.item_description[i][j]); - } - - // identification status - // how many types? - marshallByte(th, 4); - // how many subtypes? - marshallByte(th, 50); - - // this is really dumb. We copy the id[] array from itemname - // to the stack, for no good reason that I can see. - char identy[4][50]; - - save_id(identy); - - for (i = 0; i < 4; ++i) - { - for (j = 0; j < 50; ++j) - marshallByte(th, identy[i][j]); - } - - // how many unique items? - marshallByte(th, 50); - for (j = 0; j < 50; ++j) - { - marshallByte(th,you.unique_items[j]); /* unique items */ - marshallByte(th,you.had_book[j]); - } - - // how many unrandarts? - marshallShort(th, NO_UNRANDARTS); - - for (j = 0; j < NO_UNRANDARTS; ++j) - marshallBoolean(th, does_unrandart_exist(j)); -} - -static void tag_construct_you_dungeon(struct tagHeader &th) -{ - int i,j; - - // how many unique creatures? - marshallByte(th, 50); - for (j = 0; j < 50; ++j) - marshallByte(th,you.unique_creatures[j]); /* unique beasties */ - - // how many branches? - marshallByte(th, MAX_BRANCHES); - for (j = 0; j < 30; ++j) - { - marshallByte(th,you.branch_stairs[j]); - marshallByte(th,stair_level[j]); - } - - // how many levels? - marshallShort(th, MAX_LEVELS); - for (i = 0; i < MAX_LEVELS; ++i) - { - for (j = 0; j < MAX_BRANCHES; ++j) - { - marshallByte(th,altars_present[i][j]); - marshallByte(th,feature[i][j]); - marshallBoolean(th,tmp_file_pairs[i][j]); - } - } -} - -static void tag_read_you(struct tagHeader &th, char minorVersion) -{ - char buff[20]; // For birth date - int i,j; - char count_c; - short count_s; - - unmarshallString(th, you.your_name, 30); - - you.religion = unmarshallByte(th); - you.piety = unmarshallByte(th); - you.invis = unmarshallByte(th); - you.conf = unmarshallByte(th); - you.paralysis = unmarshallByte(th); - you.slow = unmarshallByte(th); - you.fire_shield = unmarshallByte(th); - you.rotting = unmarshallByte(th); - you.exhausted = unmarshallByte(th); - you.deaths_door = unmarshallByte(th); - your_sign = unmarshallByte(th); - your_colour = unmarshallByte(th); - you.pet_target = unmarshallByte(th); - - you.max_level = unmarshallByte(th); - you.where_are_you = unmarshallByte(th); - you.char_direction = unmarshallByte(th); - you.your_level = unmarshallByte(th); - you.is_undead = unmarshallByte(th); - you.special_wield = unmarshallByte(th); - you.berserker = unmarshallByte(th); - you.berserk_penalty = unmarshallByte(th); - you.level_type = unmarshallByte(th); - you.synch_time = unmarshallByte(th); - you.disease = unmarshallByte(th); - you.species = unmarshallByte(th); - you.hp = unmarshallShort(th); - you.haste = unmarshallByte(th); - you.might = unmarshallByte(th); - you.levitation = unmarshallByte(th); - you.poison = unmarshallByte(th); - you.hunger = unmarshallShort(th); - - // how many you.equip? - count_c = unmarshallByte(th); - for (i = 0; i < count_c; ++i) - you.equip[i] = unmarshallByte(th); - - you.magic_points = unmarshallByte(th); - you.max_magic_points = unmarshallByte(th); - you.strength = unmarshallByte(th); - you.intel = unmarshallByte(th); - you.dex = unmarshallByte(th); - you.confusing_touch = unmarshallByte(th); - you.sure_blade = unmarshallByte(th); - you.hit_points_regeneration = unmarshallByte(th); - you.magic_points_regeneration = unmarshallByte(th); - - you.hit_points_regeneration = unmarshallShort(th) / 100; - you.experience = unmarshallLong(th); - you.gold = unmarshallLong(th); - - you.char_class = unmarshallByte(th); - you.experience_level = unmarshallByte(th); - you.exp_available = unmarshallLong(th); - - /* max values */ - you.max_strength = unmarshallByte(th); - you.max_intel = unmarshallByte(th); - you.max_dex = unmarshallByte(th); - - you.base_hp = unmarshallShort(th); - you.base_hp2 = unmarshallShort(th); - you.base_magic_points = unmarshallShort(th); - you.base_magic_points2 = unmarshallShort(th); - - you.x_pos = unmarshallShort(th); - you.y_pos = unmarshallShort(th); - - unmarshallString(th, you.class_name, 30); - - you.burden = unmarshallShort(th); - - // how many spells? - you.spell_no = 0; - count_c = unmarshallByte(th); - for (i = 0; i < count_c; ++i) - { - you.spells[i] = unmarshallByte(th); - if (you.spells[i] != SPELL_NO_SPELL) - you.spell_no++; - } - - if (minorVersion >= 2) - { - count_c = unmarshallByte(th); - for (i = 0; i < count_c; i++) - you.spell_letter_table[i] = unmarshallByte(th); - - count_c = unmarshallByte(th); - for (i = 0; i < count_c; i++) - you.ability_letter_table[i] = unmarshallShort(th); - } - else - { - for (i = 0; i < 52; i++) - { - you.spell_letter_table[i] = -1; - you.ability_letter_table[i] = ABIL_NON_ABILITY; - } - - for (i = 0; i < 25; i++) - { - if (you.spells[i] != SPELL_NO_SPELL) - you.spell_letter_table[i] = i; - } - - if (you.religion != GOD_NO_GOD) - set_god_ability_slots(); - } - - // how many skills? - count_c = unmarshallByte(th); - for (j = 0; j < count_c; ++j) - { - you.skills[j] = unmarshallByte(th); - you.practise_skill[j] = unmarshallByte(th); - you.skill_points[j] = unmarshallLong(th); - - if (minorVersion >= 2) - you.skill_order[j] = unmarshallByte(th); - } - - // initialize ordering when we don't read it in: - if (minorVersion < 2) - init_skill_order(); - - // set up you.total_skill_points and you.skill_cost_level - calc_total_skill_points(); - - // how many durations? - count_c = unmarshallByte(th); - for (j = 0; j < count_c; ++j) - you.duration[j] = unmarshallByte(th); - - // how many attributes? - count_c = unmarshallByte(th); - for (j = 0; j < count_c; ++j) - you.attribute[j] = unmarshallByte(th); - - // how many mutations/demon powers? - count_s = unmarshallShort(th); - for (j = 0; j < count_s; ++j) - { - you.mutation[j] = unmarshallByte(th); - you.demon_pow[j] = unmarshallByte(th); - } - - // how many penances? - count_c = unmarshallByte(th); - for (i = 0; i < count_c; i++) - you.penance[i] = unmarshallByte(th); - - if (minorVersion >= 2) - { - count_c = unmarshallByte(th); - for (i = 0; i < count_c; i++) - you.worshipped[i] = unmarshallByte(th); - - if (minorVersion >= 5) - for (i = 0; i < count_c; i++) - you.num_gifts[i] = unmarshallShort(th); - - } - else - { - for (i = 0; i < count_c; i++) - you.worshipped[i] = false; - - if (you.religion != GOD_NO_GOD) - you.worshipped[you.religion] = true; - } - - you.gift_timeout = unmarshallByte(th); - you.normal_vision = unmarshallByte(th); - you.current_vision = unmarshallByte(th); - you.hell_exit = unmarshallByte(th); - - // elapsed time - you.elapsed_time = (double)unmarshallFloat(th); - - if (minorVersion >= 1) - { - // wizard mode - you.wizard = (bool) unmarshallByte(th); - - // time of character creation - unmarshallString( th, buff, 20 ); - you.birth_time = parse_date_string( buff ); - } - - if (minorVersion >= 2) - { - you.real_time = unmarshallLong(th); - you.num_turns = unmarshallLong(th); - } - else - { - you.real_time = -1; - you.num_turns = -1; - } - - // you.magic_contamination 05/03/05 - if (minorVersion >= 3) - { - you.magic_contamination = unmarshallShort(th); - } -} - -static void tag_convert_to_4_3_item( item_def &item ) -{ - const unsigned char plus = item.plus; - const unsigned char plus2 = item.plus2; - const unsigned char ident = item.flags; - const unsigned char special = item.special; - - if (item.quantity <= 0) - return; - - // First, convert ident into flags: - item.flags = (ident == 3) ? ISFLAG_IDENT_MASK : - (ident > 0) ? ISFLAG_KNOW_CURSE - : 0; - - switch (item.base_type) - { - case OBJ_ARMOUR: - if ((ident == 1 && special % 30 >= 25) || ident == 2) - item.flags |= ISFLAG_KNOW_TYPE; - - // Convert special values - item.special %= 30; - if (item.special < 25) - { - if (item.sub_type == ARM_HELMET) - { - item.plus2 = plus2 % 30; - set_helmet_desc( item, (special / 30) << 8 ); - } - else - { - switch (special / 30) - { - case DARM_EMBROIDERED_SHINY: - set_equip_desc( item, ISFLAG_EMBROIDERED_SHINY ); - break; - case DARM_RUNED: - set_equip_desc( item, ISFLAG_RUNED ); - break; - case DARM_GLOWING: - set_equip_desc( item, ISFLAG_GLOWING ); - break; - case DARM_ELVEN: - set_equip_race( item, ISFLAG_ELVEN ); - break; - case DARM_DWARVEN: - set_equip_race( item, ISFLAG_DWARVEN ); - break; - case DARM_ORCISH: - set_equip_race( item, ISFLAG_ORCISH ); - break; - default: - break; - } - } - } - else if (item.special == 25) - { - item.flags |= ISFLAG_UNRANDART; - item.special = 0; - } - else - { - item.flags |= ISFLAG_RANDART; - - // calc old seed - item.special = item.base_type * special - + item.sub_type * (plus % 100) - + plus2 * 100; - } - break; - - case OBJ_WEAPONS: - if ((ident == 1 && (special < 180 && special % 30 >= 25)) || ident == 2) - item.flags |= ISFLAG_KNOW_TYPE; - - // Convert special values - if (special < 181) // don't mangle fixed artefacts - { - item.special %= 30; - if (item.special < 25) - { - switch (special / 30) - { - case DWPN_RUNED: - set_equip_desc( item, ISFLAG_RUNED ); - break; - case DWPN_GLOWING: - set_equip_desc( item, ISFLAG_GLOWING ); - break; - case DWPN_ORCISH: - set_equip_race( item, ISFLAG_ORCISH ); - break; - case DWPN_ELVEN: - set_equip_race( item, ISFLAG_ELVEN ); - break; - case DWPN_DWARVEN: - set_equip_race( item, ISFLAG_DWARVEN ); - break; - default: - break; - } - } - else if (item.special == 25) - { - item.flags |= ISFLAG_UNRANDART; - item.special = 0; - } - else - { - item.flags |= ISFLAG_RANDART; - - // calc old seed - item.special = item.base_type * special - + item.sub_type * (plus % 100) - + plus2 * 100; - } - } - break; - - case OBJ_MISSILES: - // Needles were moved into the bonus eggplant spot. -- bwr - if (item.sub_type == 6) - item.sub_type = MI_NEEDLE; - - if (ident == 2) - item.flags |= ISFLAG_KNOW_TYPE; - - // Convert special values - item.special %= 30; - switch (special / 30) - { - case DAMMO_ORCISH: - set_equip_race( item, ISFLAG_ORCISH ); - break; - case DAMMO_ELVEN: - set_equip_race( item, ISFLAG_ELVEN ); - break; - case DAMMO_DWARVEN: - set_equip_race( item, ISFLAG_DWARVEN ); - break; - default: - break; - } - break; - - case OBJ_WANDS: - if (ident == 2) - item.flags |= ISFLAG_KNOW_PLUSES; - break; - - case OBJ_JEWELLERY: - if (ident == 1 && (special == 200 || special == 201)) - item.flags |= ISFLAG_KNOW_TYPE; - else if (ident == 2) - item.flags |= (ISFLAG_KNOW_TYPE | ISFLAG_KNOW_PLUSES); - - if (special == 201) - { - item.flags |= ISFLAG_UNRANDART; - item.special = 0; - } - else if (special == 200) - { - item.flags |= ISFLAG_RANDART; - - // calc old seed - item.special = item.base_type * special - + item.sub_type * (plus % 100) - + plus2 * 100; - } - break; - - default: - if (ident > 0) - item.flags |= ISFLAG_KNOW_TYPE; - break; - } - - - // Second, convert plus and plus2 - if (item.base_type == OBJ_WEAPONS - || item.base_type == OBJ_MISSILES - || item.base_type == OBJ_ARMOUR - || item.base_type == OBJ_JEWELLERY) - { - item.plus = plus; - - // item is cursed: - if (plus > 100) - { - item.plus -= 100; - item.flags |= ISFLAG_CURSED; - } - - // Weapons use both as pluses. - // Non-artefact jewellery uses both as pluses. - // Artefact jewellery has literal values for both pluses. - // Armour and Missiles only use plus for their plus value. - // Armour has literal usage of plus2 for sub-subtypes. - if (item.base_type != OBJ_JEWELLERY) - { - item.plus -= 50; - - if (item.base_type == OBJ_WEAPONS) - item.plus2 -= 50; - } - else if (special != 200) - { - // regular jewellery & unrandarts -- unused pluses were 0s - if (item.plus) - item.plus -= 50; - - if (item.plus2) - item.plus2 -= 50; - } - else if (special == 200) - { - // Randart jewellery used pluses only as seeds, right now - // they're always zero (since random artefact rings avoid - // base types with pluses). - item.plus = 0; - item.plus2 = 0; - } - } -} - -static void tag_read_you_items(struct tagHeader &th, char minorVersion) -{ - int i,j; - char count_c, count_c2; - short count_s; - - // how many inventory slots? - count_c = unmarshallByte(th); - for (i = 0; i < count_c; ++i) - { - you.inv[i].orig_monnum = you.inv[i].orig_place = 0; - if (minorVersion < 1) - { - you.inv[i].base_type = (unsigned char) unmarshallByte(th); - you.inv[i].sub_type = (unsigned char) unmarshallByte(th); - you.inv[i].plus = (unsigned char) unmarshallByte(th); - you.inv[i].special = (unsigned char) unmarshallByte(th); - you.inv[i].colour = (unsigned char) unmarshallByte(th); - you.inv[i].flags = (unsigned char) unmarshallByte(th); - you.inv[i].quantity = unmarshallShort(th); - you.inv[i].plus2 = (unsigned char) unmarshallByte(th); - - tag_convert_to_4_3_item( you.inv[i] ); - } - else - { - you.inv[i].base_type = (unsigned char) unmarshallByte(th); - you.inv[i].sub_type = (unsigned char) unmarshallByte(th); - you.inv[i].plus = unmarshallShort(th); - you.inv[i].special = unmarshallLong(th); - you.inv[i].colour = (unsigned char) unmarshallByte(th); - you.inv[i].flags = (unsigned long) unmarshallLong(th); - you.inv[i].quantity = unmarshallShort(th); - you.inv[i].plus2 = unmarshallShort(th); - - if (minorVersion >= 4) - { - you.inv[i].orig_place = unmarshallShort(th); - you.inv[i].orig_monnum = unmarshallShort(th); - } - } - - // these never need to be saved for items in the inventory -- bwr - you.inv[i].x = -1; - you.inv[i].y = -1; - you.inv[i].link = i; - you.inv[i].slot = index_to_letter(i); - } - - // item descrip for each type & subtype - // how many types? - count_c = unmarshallByte(th); - // how many subtypes? - count_c2 = unmarshallByte(th); - for (i = 0; i < count_c; ++i) - { - for (j = 0; j < count_c2; ++j) - you.item_description[i][j] = unmarshallByte(th); - } - - // identification status - // how many types? - count_c = unmarshallByte(th); - // how many subtypes? - count_c2 = unmarshallByte(th); - - // argh.. this is awful. - for (i = 0; i < count_c; ++i) - { - for (j = 0; j < count_c2; ++j) - { - char ch; - ch = unmarshallByte(th); - - switch (i) - { - case IDTYPE_WANDS: - set_ident_type(OBJ_WANDS, j, ch); - break; - case IDTYPE_SCROLLS: - set_ident_type(OBJ_SCROLLS, j, ch); - break; - case IDTYPE_JEWELLERY: - set_ident_type(OBJ_JEWELLERY, j, ch); - break; - case IDTYPE_POTIONS: - set_ident_type(OBJ_POTIONS, j, ch); - break; - } - } - } - - // how many unique items? - count_c = unmarshallByte(th); - for (j = 0; j < count_c; ++j) - { - you.unique_items[j] = unmarshallByte(th); - you.had_book[j] = unmarshallByte(th); - } - - // how many unrandarts? - count_s = unmarshallShort(th); - for (j = 0; j < count_s; ++j) - set_unrandart_exist(j, unmarshallBoolean(th)); - - // # of unrandarts could certainly change. If it does, - // the new ones won't exist yet - zero them out. - for (; j < NO_UNRANDARTS; j++) - set_unrandart_exist(j, 0); -} - -static void tag_read_you_dungeon(struct tagHeader &th) -{ - int i,j; - char count_c; - short count_s; - - // how many unique creatures? - count_c = unmarshallByte(th); - for (j = 0; j < count_c; ++j) - you.unique_creatures[j] = unmarshallByte(th); - - // how many branches? - count_c = unmarshallByte(th); - for (j = 0; j < count_c; ++j) - { - you.branch_stairs[j] = unmarshallByte(th); - stair_level[j] = unmarshallByte(th); - } - - // how many levels? - count_s = unmarshallShort(th); - for (i = 0; i < count_s; ++i) - { - for (j = 0; j < count_c; ++j) - { - altars_present[i][j] = unmarshallByte(th); - feature[i][j] = unmarshallByte(th); - tmp_file_pairs[i][j] = unmarshallBoolean(th); - } - } -} - -// ------------------------------- level tags ---------------------------- // - -static void tag_construct_level(struct tagHeader &th) -{ - int i; - int count_x, count_y; - - marshallFloat(th, (float)you.elapsed_time); - - // map grids - // how many X? - marshallShort(th, GXM); - // how many Y? - marshallShort(th, GYM); - for (count_x = 0; count_x < GXM; count_x++) - { - for (count_y = 0; count_y < GYM; count_y++) - { - marshallByte(th, grd[count_x][count_y]); - marshallShort(th, env.map[count_x][count_y]); - marshallByte(th, env.cgrid[count_x][count_y]); - } - } - - marshallShort(th, env.cloud_no); - - // how many clouds? - marshallShort(th, MAX_CLOUDS); - for (i = 0; i < MAX_CLOUDS; i++) - { - marshallByte(th, env.cloud[i].x); - marshallByte(th, env.cloud[i].y); - marshallByte(th, env.cloud[i].type); - marshallShort(th, env.cloud[i].decay); - } - - // how many shops? - marshallByte(th, 5); - for (i = 0; i < 5; i++) - { - marshallByte(th, env.shop[i].keeper_name[0]); - marshallByte(th, env.shop[i].keeper_name[1]); - marshallByte(th, env.shop[i].keeper_name[2]); - marshallByte(th, env.shop[i].x); - marshallByte(th, env.shop[i].y); - marshallByte(th, env.shop[i].greed); - marshallByte(th, env.shop[i].type); - marshallByte(th, env.shop[i].level); - } -} - -static void tag_construct_level_items(struct tagHeader &th) -{ - int i; - - // how many traps? - marshallShort(th, MAX_TRAPS); - for (i = 0; i < MAX_TRAPS; ++i) - { - marshallByte(th, env.trap[i].type); - marshallByte(th, env.trap[i].x); - marshallByte(th, env.trap[i].y); - } - - // how many items? - marshallShort(th, MAX_ITEMS); - for (i = 0; i < MAX_ITEMS; ++i) - { - marshallByte(th, mitm[i].base_type); - marshallByte(th, mitm[i].sub_type); - marshallShort(th, mitm[i].plus); - marshallShort(th, mitm[i].plus2); - marshallLong(th, mitm[i].special); - marshallShort(th, mitm[i].quantity); - - marshallByte(th, mitm[i].colour); - marshallShort(th, mitm[i].x); - marshallShort(th, mitm[i].y); - marshallLong(th, mitm[i].flags); - - marshallShort(th, mitm[i].link); // unused - marshallShort(th, igrd[mitm[i].x][mitm[i].y]); // unused - - marshallByte(th, mitm[i].slot); - - marshallShort(th, mitm[i].orig_place); - marshallShort(th, mitm[i].orig_monnum); - } -} - -static void tag_construct_level_monsters(struct tagHeader &th) -{ - int i,j; - - // how many mons_alloc? - marshallByte(th, 20); - for (i = 0; i < 20; ++i) - marshallShort(th, env.mons_alloc[i]); - - // how many monsters? - marshallShort(th, MAX_MONSTERS); - // how many monster enchantments? - marshallByte(th, NUM_MON_ENCHANTS); - // how many monster inventory slots? - marshallByte(th, NUM_MONSTER_SLOTS); - - for (i = 0; i < MAX_MONSTERS; i++) - { - marshallByte(th, menv[i].armour_class); - marshallByte(th, menv[i].evasion); - marshallByte(th, menv[i].hit_dice); - marshallByte(th, menv[i].speed); - marshallByte(th, menv[i].speed_increment); - marshallByte(th, menv[i].behaviour); - marshallByte(th, menv[i].x); - marshallByte(th, menv[i].y); - marshallByte(th, menv[i].target_x); - marshallByte(th, menv[i].target_y); - marshallByte(th, menv[i].flags); - - for (j = 0; j < NUM_MON_ENCHANTS; j++) - marshallByte(th, menv[i].enchantment[j]); - - marshallShort(th, menv[i].type); - marshallShort(th, menv[i].hit_points); - marshallShort(th, menv[i].max_hit_points); - marshallShort(th, menv[i].number); - - for (j = 0; j < NUM_MONSTER_SLOTS; j++) - marshallShort(th, menv[i].inv[j]); - } -} - -void tag_construct_level_attitude(struct tagHeader &th) -{ - int i; - - // how many monsters? - marshallShort(th, MAX_MONSTERS); - - for (i = 0; i < MAX_MONSTERS; i++) - { - marshallByte(th, menv[i].attitude); - marshallShort(th, menv[i].foe); - } -} - - -static void tag_read_level( struct tagHeader &th, char minorVersion ) -{ - int i,j; - int gx, gy; - - env.elapsed_time = (double)unmarshallFloat(th); - - // map grids - // how many X? - gx = unmarshallShort(th); - // how many Y? - gy = unmarshallShort(th); - for (i = 0; i < gx; i++) - { - for (j = 0; j < gy; j++) - { - grd[i][j] = unmarshallByte(th); - - if (minorVersion < 8) - env.map[i][j] = (unsigned char) unmarshallByte(th); - else - env.map[i][j] = (unsigned short) unmarshallShort(th); - - if ((env.map[i][j] & 0xFF) == 201) // what is this?? - env.map[i][j] = (env.map[i][j] & 0xFF00U) | 239; - - mgrd[i][j] = NON_MONSTER; - env.cgrid[i][j] = unmarshallByte(th); - - if (minorVersion < 3) - { - // increased number of clouds to 100 in 4.3 - if (env.cgrid[i][j] > 30) - env.cgrid[i][j] = 101; - } - } - } - - env.cloud_no = unmarshallShort(th); - - // how many clouds? - gx = unmarshallShort(th); - for (i = 0; i < gx; i++) - { - env.cloud[i].x = unmarshallByte(th); - env.cloud[i].y = unmarshallByte(th); - env.cloud[i].type = unmarshallByte(th); - env.cloud[i].decay = unmarshallShort(th); - } - - // how many shops? - gx = unmarshallByte(th); - for (i = 0; i < gx; i++) - { - env.shop[i].keeper_name[0] = unmarshallByte(th); - env.shop[i].keeper_name[1] = unmarshallByte(th); - env.shop[i].keeper_name[2] = unmarshallByte(th); - env.shop[i].x = unmarshallByte(th); - env.shop[i].y = unmarshallByte(th); - env.shop[i].greed = unmarshallByte(th); - env.shop[i].type = unmarshallByte(th); - env.shop[i].level = unmarshallByte(th); - } -} - -static void tag_read_level_items(struct tagHeader &th, char minorVersion) -{ - int i; - int count; - - // how many traps? - count = unmarshallShort(th); - for (i = 0; i < count; ++i) - { - env.trap[i].type = unmarshallByte(th); - env.trap[i].x = unmarshallByte(th); - env.trap[i].y = unmarshallByte(th); - } - - // how many items? - count = unmarshallShort(th); - for (i = 0; i < count; ++i) - { - if (minorVersion < 3) - { - mitm[i].base_type = (unsigned char) unmarshallByte(th); - mitm[i].sub_type = (unsigned char) unmarshallByte(th); - mitm[i].plus = (unsigned char) unmarshallByte(th); - mitm[i].plus2 = (unsigned char) unmarshallByte(th); - mitm[i].special = (unsigned char) unmarshallByte(th); - mitm[i].quantity = unmarshallLong(th); - mitm[i].colour = (unsigned char) unmarshallByte(th); - mitm[i].x = (unsigned char) unmarshallByte(th); - mitm[i].y = (unsigned char) unmarshallByte(th); - mitm[i].flags = (unsigned char) unmarshallByte(th); - - tag_convert_to_4_3_item( mitm[i] ); - } - else - { - mitm[i].base_type = (unsigned char) unmarshallByte(th); - mitm[i].sub_type = (unsigned char) unmarshallByte(th); - mitm[i].plus = unmarshallShort(th); - mitm[i].plus2 = unmarshallShort(th); - mitm[i].special = unmarshallLong(th); - mitm[i].quantity = unmarshallShort(th); - mitm[i].colour = (unsigned char) unmarshallByte(th); - mitm[i].x = unmarshallShort(th); - mitm[i].y = unmarshallShort(th); - mitm[i].flags = (unsigned long) unmarshallLong(th); - } - - // [dshaligram] FIXME, remove this kludge when ARM_CAP is fully - // integrated. - if (mitm[i].base_type == OBJ_ARMOUR && mitm[i].sub_type == ARM_CAP) - mitm[i].sub_type = ARM_HELMET; - - // pre 4.2 files had monster items stacked at (2,2) -- moved to (0,0) - if (minorVersion < 2 && mitm[i].x == 2 && mitm[i].y == 2) - { - mitm[i].x = 0; - mitm[i].y = 0; - } - - unmarshallShort(th); // mitm[].link -- unused - unmarshallShort(th); // igrd[mitm[i].x][mitm[i].y] -- unused - - if (minorVersion >= 6) - { - mitm[i].slot = unmarshallByte(th); - } - - if (minorVersion >= 7) - { - mitm[i].orig_place = unmarshallShort(th); - mitm[i].orig_monnum = unmarshallShort(th); - } - else - { - mitm[i].orig_place = 0; - mitm[i].orig_monnum = 0; - } - } -} - -static void tag_read_level_monsters(struct tagHeader &th, char minorVersion) -{ - int i,j; - int count, ecount, icount; - - // how many mons_alloc? - count = unmarshallByte(th); - for (i = 0; i < count; ++i) - env.mons_alloc[i] = unmarshallShort(th); - - // how many monsters? - count = unmarshallShort(th); - // how many monster enchantments? - ecount = unmarshallByte(th); - // how many monster inventory slots? - icount = unmarshallByte(th); - - for (i = 0; i < count; i++) - { - menv[i].armour_class = unmarshallByte(th); - menv[i].evasion = unmarshallByte(th); - menv[i].hit_dice = unmarshallByte(th); - menv[i].speed = unmarshallByte(th); - // Avoid sign extension when loading files (Elethiomel's hang) - menv[i].speed_increment = (unsigned char) unmarshallByte(th); - menv[i].behaviour = unmarshallByte(th); - menv[i].x = unmarshallByte(th); - menv[i].y = unmarshallByte(th); - menv[i].target_x = unmarshallByte(th); - menv[i].target_y = unmarshallByte(th); - menv[i].flags = unmarshallByte(th); - - // VERSION NOTICE: for pre 4.2 files, flags was either 0 - // or 1. Now, we can transfer ENCH_CREATED_FRIENDLY over - // from the enchantments array to flags. - // Also need to take care of ENCH_FRIEND_ABJ_xx flags - - for (j = 0; j < ecount; j++) - menv[i].enchantment[j] = unmarshallByte(th); - - if (minorVersion < 2) - { - menv[i].flags = 0; - for(j=0; j<NUM_MON_ENCHANTS; j++) - { - if (j>=ecount) - menv[i].enchantment[j] = ENCH_NONE; - else - { - if (menv[i].enchantment[j] == 71) // old ENCH_CREATED_FRIENDLY - { - menv[i].enchantment[j] = ENCH_NONE; - menv[i].flags |= MF_CREATED_FRIENDLY; - } - if (menv[i].enchantment[j] >= 65 // old ENCH_FRIEND_ABJ_I - && menv[i].enchantment[j] <= 70) // old ENCH_FRIEND_ABJ_VI - { - menv[i].enchantment[j] -= (65 - ENCH_ABJ_I); - menv[i].flags |= MF_CREATED_FRIENDLY; - } - } - } - } // end minorversion < 2 - - menv[i].type = unmarshallShort(th); - menv[i].hit_points = unmarshallShort(th); - menv[i].max_hit_points = unmarshallShort(th); - menv[i].number = unmarshallShort(th); - - for (j = 0; j < icount; j++) - menv[i].inv[j] = unmarshallShort(th); - - // place monster - if (menv[i].type != -1) - mgrd[menv[i].x][menv[i].y] = i; - } -} - -void tag_read_level_attitude(struct tagHeader &th) -{ - int i, count; - - // how many monsters? - count = unmarshallShort(th); - - for (i = 0; i < count; i++) - { - menv[i].attitude = unmarshallByte(th); - menv[i].foe = unmarshallShort(th); - } -} - -void tag_missing_level_attitude() -{ - // we don't really have to do a lot here. - // just set foe to MHITNOT; they'll pick up - // a foe first time through handle_monster() if - // there's one around. - - // as for attitude, a couple simple checks - // can be used to determine friendly/neutral/ - // hostile. - int i; - bool isFriendly; - unsigned int new_beh = BEH_WANDER; - - for(i=0; i<MAX_MONSTERS; i++) - { - // only do actual monsters - if (menv[i].type < 0) - continue; - - isFriendly = testbits(menv[i].flags, MF_CREATED_FRIENDLY); - - menv[i].foe = MHITNOT; - - switch(menv[i].behaviour) - { - case 0: // old BEH_SLEEP - new_beh = BEH_SLEEP; // don't wake sleepers - break; - case 3: // old BEH_FLEE - case 10: // old BEH_FLEE_FRIEND - new_beh = BEH_FLEE; - break; - case 1: // old BEH_CHASING_I - case 6: // old BEH_FIGHT - new_beh = BEH_SEEK; - break; - case 7: // old BEH_ENSLAVED - if (!mons_has_ench(&menv[i], ENCH_CHARM)) - isFriendly = true; - break; - default: - break; - } - - menv[i].attitude = (isFriendly)?ATT_FRIENDLY : ATT_HOSTILE; - menv[i].behaviour = new_beh; - menv[i].foe_memory = 0; - } -} - - -// ------------------------------- ghost tags ---------------------------- // - -static void tag_construct_ghost(struct tagHeader &th) -{ - int i; - - marshallString(th, ghost.name, 20); - - // how many ghost values? - marshallByte(th, 20); - - for (i = 0; i < 20; i++) - marshallShort( th, ghost.values[i] ); -} - -static void tag_read_ghost(struct tagHeader &th, char minorVersion) -{ - int i, count_c; - - snprintf( info, INFO_SIZE, "minor version = %d", minorVersion ); - - unmarshallString(th, ghost.name, 20); - - // how many ghost values? - count_c = unmarshallByte(th); - - for (i = 0; i < count_c; i++) - { - // for version 4.4 we moved from unsigned char to shorts -- bwr - if (minorVersion < 4) - ghost.values[i] = unmarshallByte(th); - else - ghost.values[i] = unmarshallShort(th); - } - - if (minorVersion < 4) - { - // Getting rid 9of hopefulling the last) of this silliness -- bwr - if (ghost.values[ GVAL_RES_FIRE ] >= 97) - ghost.values[ GVAL_RES_FIRE ] -= 100; - - if (ghost.values[ GVAL_RES_COLD ] >= 97) - ghost.values[ GVAL_RES_COLD ] -= 100; - } -} - -// ----------------------------------------------------------------------- // |