Exemple #1
0
/*
 * Write the char to the file.
 *
 * @param ch the character to be written
 * @param fp the file to write to
 */
void fwrite_char( struct char_data *ch, FILE *fp )
{
  extern struct race_data * races;
  
  struct affected_type *paf;
  int          sn, i;
  
  fprintf( fp, "#%s\n", IS_NPC( ch ) ? "MOB" : "PLAYER"		);
  
  fprintf( fp, "Name        %s~\n",	GET_NAME(ch)			);
  fprintf( fp, "ShtDsc      %s~\n",	GET_SHORT_DESC(ch) ?
	   GET_SHORT_DESC(ch) : "" );
  fprintf( fp, "LngDsc      %s~\n",	GET_LONG_DESC(ch) ?
	   GET_LONG_DESC(ch) : "" );
  fprintf( fp, "Dscr        %s~\n",	GET_DESCRIPTION(ch) ?
	   GET_DESCRIPTION(ch) : "" );
  // fprintf( fp, "Prmpt       %s~\n",	ch->pcdata->prompt	);
  fprintf( fp, "Sx          %d\n",	GET_SEX(ch)			);
  fprintf( fp, "Race        %s~\n",	races[ (int)GET_RACE(ch) ].name );
  fprintf( fp, "Lvl         %d\n",	GET_LEVEL(ch)			);
  fprintf( fp, "Trst        %d\n",	GET_TRUST(ch)			);
  /*
    fprintf( fp, "Playd       %ld\n",
    GET_PLAYED(ch) + (int)( time( 0 ) - GET_LOGON(ch) )		);
  */
  // fprintf( fp, "Note        %ld\n",   (unsigned long)ch->last_note );
  fprintf( fp, "Room        %ld\n",
	   (  ch->in_room == NOWHERE && ch->was_in_room )
	   ? ch->was_in_room : ch->in_room );
  
  fprintf( fp, "HpMnMv      %d %d %d %d %d %d\n",
	   GET_HIT(ch), GET_MAX_HIT(ch),
	   GET_MANA(ch), GET_MAX_MANA(ch),
	   GET_MOVE(ch), GET_MAX_MOVE(ch) );
  fprintf( fp, "Gold        %ld\n",	GET_GOLD(ch)		);
  fprintf( fp, "Exp         %ld\n",	GET_EXP(ch)		);
  fprintf( fp, "Act         %lld\n",  PLR_FLAGS(ch)           );
  fprintf( fp, "Act2        %lld\n",  PLR2_FLAGS(ch)          );
  fprintf( fp, "Pref        %lld\n",  PRF_FLAGS(ch)		);
  fprintf( fp, "Pref2       %lld\n",  PRF2_FLAGS(ch)		);
  fprintf( fp, "AffdBy      %lld\n",	AFF_FLAGS(ch)		);
  fprintf( fp, "AffdBy2     %lld\n",	AFF2_FLAGS(ch)		);
  /* Bug fix from Alander */
  fprintf( fp, "Pos         %d\n",
	   GET_POS(ch) == POS_FIGHTING ? POS_STANDING : GET_POS(ch) );
  fprintf( fp, "Prac        %d\n",    GET_PRACTICES(ch)       );
  fprintf( fp, "PAlign      %d\n",	GET_PERMALIGN(ch)	);
  fprintf( fp, "CAlign      %d\n",	GET_ALIGNMENT(ch)	);
  fprintf( fp, "SavThr      " );
  for ( i = 0; i < NUM_SAVES; i++ )
    fprintf( fp, "%d%s",    GET_SAVE(ch, i), (i != NUM_SAVES-1 ? ", " : "\n")	);
  fprintf( fp, "Hitroll     %d\n",	GET_HITROLL(ch)		);
  fprintf( fp, "Damroll     %d\n",	GET_DAMROLL(ch)		);
  fprintf( fp, "Armr        " );
  for ( i = 0; i < ARMOR_LIMIT; i++ )
    fprintf( fp, "%d%s",   GET_AC(ch, i), (i != ARMOR_LIMIT-1 ? ", " : "\n") );
  fprintf( fp, "Wimp        %d\n",	GET_WIMP_LEV(ch)	);
  
  if ( IS_NPC( ch ) ) {
    fprintf( fp, "Vnum        %ld\n",	GET_MOB_VNUM(ch)	);
  } else {
    fprintf( fp, "Paswd       %s~\n",	GET_PASSWD(ch)		);
    fprintf( fp, "Poofin      %s~\n",	POOFIN(ch) ?
	     POOFIN(ch) : "" );
    fprintf( fp, "Poofout     %s~\n",	POOFOUT(ch) ?
	     POOFOUT(ch) : "" );
    fprintf( fp, "Ttle        %s~\n",	GET_TITLE(ch) ?
	     GET_TITLE(ch) : "" );
    fprintf( fp, "AtrPrm      %d/%d %d %d %d %d %d %d\n",
	     ch->real_abils.str,
	     ch->real_abils.str_add,
	     ch->real_abils.intel,
	     ch->real_abils.wis,
	     ch->real_abils.dex,
	     ch->real_abils.con,
	     ch->real_abils.cha,
	     ch->real_abils.will );
    
    fprintf( fp, "AtrMd       %d/%d %d %d %d %d %d %d\n",
	     ch->aff_abils.str, 
	     ch->aff_abils.str_add, 
	     ch->aff_abils.intel, 
	     ch->aff_abils.wis, 
	     ch->aff_abils.dex, 
	     ch->aff_abils.con, 
	     ch->aff_abils.cha, 
	     ch->aff_abils.will );
    
    fprintf( fp, "Conditions  " );
    for ( i = 0; i < MAX_COND; i++ )
      fprintf( fp, "%d%s", GET_COND(ch, i), (i != MAX_COND-1 ? ", " : "\n") );
    
    fprintf( fp, "Addictions  " );
    for ( i = 0; i < MAX_COND; i++ )
      fprintf( fp, "%d%s", GET_ADDICT(ch, i), (i != MAX_COND-1 ? ", " : "\n") );
    
    for ( sn = 0; sn < MAX_SKILLS; sn++ ) {
      if ( skill_name( sn ) &&
           strcmp( skill_name( sn ), "!UNUSED!" ) &&
           GET_SKILL(ch, sn) > 0 ) {
	fprintf( fp, "Skill       %d '%s'\n",
		 GET_SKILL(ch, sn),
		 skill_name( sn ) );
      }
    }
  }
  
  for ( paf = ch->affected; paf; paf = paf->next )  {
    fprintf( fp, "Afft       %18s~ %3d %3d %3d %lld\n",
	     skill_name( paf->type ),
	     paf->duration,
	     paf->modifier,
	     paf->location,
	     paf->bitvector );
  }
  
  for ( paf = ch->affected2; paf; paf = paf->next )  {
    fprintf( fp, "Afft2       %18s~ %3d %3d %3d %lld\n",
	     skill_name( paf->type ),
	     paf->duration,
	     paf->modifier,
	     paf->location,
	     paf->bitvector );
  }
  
  fprintf( fp, "End\n\n" );
  return;
}
Exemple #2
0
/*
 * Read in a char.
 */
int fread_char( struct char_data *ch, FILE *fp )
{
  int         error_count = 0;
  char        *word;
  char        buf [ MAX_STRING_LENGTH ];
  struct affected_type *paf;
  int         sn;
  int         i;
  int         j;
  int         status;
  int         status1;
  char        *p;
  int         tmpi;
  int         num_keys;
  int         last_key = 0;
  
  char        def_sdesc  [] = "Your short description was corrupted.";
  char        def_ldesc  [] = "Your long description was corrupted.";
  char        def_desc   [] = "Your description was corrupted.";
  char        def_title  [] = "Your title was corrupted.";
  
  struct key_data key_tab [] = {
    { "ShtDsc", TRUE,  (int) &def_sdesc,	{ &GET_SHORT_DESC(ch),   NULL } },
    { "LngDsc", TRUE,  (int) &def_ldesc,	{ &GET_LONG_DESC(ch),    NULL } },
    { "Dscr",   TRUE,  (int) &def_desc,		{ &GET_DESCRIPTION(ch),  NULL } },
    { "Sx",     FALSE, SEX_MALE,		{ &GET_SEX(ch),          NULL } },
    { "Race",   FALSE, MAND,			{ &GET_RACE(ch),         NULL } },
    { "Lvl",    FALSE, MAND,			{ &GET_LEVEL(ch),        NULL } },
    { "Trst",   FALSE, 0,			{ &GET_TRUST(ch),        NULL } },
    { "HpMnMv", FALSE, MAND,			{ &GET_HIT(ch),
						  &GET_MAX_HIT(ch),
						  &GET_MANA(ch),
						  &GET_MAX_MANA(ch),
						  &GET_MOVE(ch),
						  &GET_MAX_MOVE(ch),     NULL } },
    { "Gold",   FALSE, 0,			{ &GET_GOLD(ch),         NULL } },
    { "Exp",    FALSE, MAND,			{ &GET_EXP(ch),          NULL } },
    { "Act",     FALSE, DEFLT,			{ &PLR_FLAGS(ch),        NULL } },
    { "Act2",    FALSE, DEFLT,			{ &PLR2_FLAGS(ch),       NULL } },
    { "AffdBy",  FALSE, 0,			{ &AFF_FLAGS(ch),        NULL } },
    { "AffdBy2", FALSE, 0,			{ &AFF2_FLAGS(ch),       NULL } },
    { "Pref",    FALSE, 0,			{ &PRF_FLAGS(ch),        NULL } },
    { "Pref2",   FALSE, 0,			{ &PRF2_FLAGS(ch),       NULL } },
    { "Pos",    FALSE, POS_STANDING, 		{ &GET_POS(ch),          NULL } },
    { "Prac",   FALSE, MAND,			{ &GET_PRACTICES(ch),    NULL } },
    { "PAlign",  FALSE, 0,			{ &GET_PERMALIGN(ch),    NULL } },
    { "CAlign",  FALSE, 0,			{ &GET_ALIGNMENT(ch),    NULL } },
    { "Ttle",   TRUE,  (int) &def_title,	{ &GET_TITLE(ch),        NULL } },
#if 0
    { "SavThr", FALSE, MAND,			{ &ch->saving_throw,  NULL } },
    { "Hit",    FALSE, MAND,			{ &ch->hitroll,       NULL } },
    { "Dam",    FALSE, MAND,			{ &ch->damroll,       NULL } },
    { "Armr",   FALSE, MAND,			{ &ch->armor,         NULL } },
    { "Wimp",   FALSE, 10,			{ &ch->wimpy,         NULL } },
    { "Deaf",   FALSE, 0,			{ &ch->deaf,          NULL } },
    { "Immskll",TRUE,  DEFLT,			{ &ch->pcdata->immskll,
                                                  NULL } },
    { "AtrPrm", FALSE, MAND,			{ &ch->pcdata->perm_str,
						  &ch->pcdata->perm_int,
						  &ch->pcdata->perm_wis,
						  &ch->pcdata->perm_dex,
						  &ch->pcdata->perm_con,
                                                  NULL } },
    { "AtrMd",  FALSE, MAND,			{ &ch->pcdata->mod_str,
						  &ch->pcdata->mod_int,
						  &ch->pcdata->mod_wis,
						  &ch->pcdata->mod_dex,
						  &ch->pcdata->mod_con,
                                                  NULL } },
    { "Cond",   FALSE, DEFLT,			{ &ch->pcdata->condition [0],
						  &ch->pcdata->condition [1],
						  &ch->pcdata->condition [2],
                                                  NULL } },
    { "Pglen",  FALSE, 20,			{ &ch->pcdata->pagelen,
                                                  NULL } },
    { "Playd",   FALSE, 0,			{ &ch->played,        NULL } },
#endif
    { "Paswd",   TRUE,  MAND,			{ &GET_PASSWD(ch),    NULL } },
    { "Poofin",  TRUE,  DEFLT,			{ &POOFIN(ch),        NULL } },
    { "Poofout", TRUE,  DEFLT,			{ &POOFOUT(ch),       NULL } },
    { "\0",     FALSE, 0                                                   } };
  
  for ( num_keys = 0; *key_tab [num_keys].key; )
    num_keys++;
  
  for ( ; !feof (fp) ; )
  {
    
    word = fread_word_stat( fp, &status );
    
    if ( !word )
    {
      log( "fread_char:  Error reading key.  EOF?" );
      fread_to_eol( fp );
      break;
    }
    
    /* This little diddy searches for the keyword
       from the last keyword found */
    
    for ( i = last_key;
          i < last_key + num_keys &&
                str_cmp (key_tab [i % num_keys].key, word); )
      i++;
    
    i = i % num_keys;
    
    if ( !str_cmp (key_tab [i].key, word) )
      last_key = i;
    else
      i = num_keys;
    
    if ( *key_tab [i].key )         /* Key entry found in key_tab */
    {
      if ( key_tab [i].string == SPECIFIED )
        log( "Key already specified." );
      
      /* Entry is a string */
      
      else
        if ( key_tab [i].string )
        {
          if ( ( p = fread_string( fp, (char*)&status ) ) && !status )
          {
            free( *(char **)key_tab [i].ptrs [0] );
            *(char **)key_tab [i].ptrs [0] = p;
          }
        }
      
      /* Entry is an integer */
        else
          for ( j = 0; key_tab [i].ptrs [j]; j++ )
          {
            tmpi = fread_number_stat( fp, &status );
            if ( !status )
              *(int *)key_tab [i].ptrs [j] = tmpi;
          }
      
      if ( status )
      {
        fread_to_eol( fp );
        continue;
      }
      else
        key_tab [i].string = SPECIFIED;
    }
    
    else if ( *word == '*' || !str_cmp( word, "Nm" ) )
      fread_to_eol( fp );
    
    else if ( !str_cmp( word, "End" ) )
      break;
    
    else if ( !str_cmp( word, "Room" ) )
    {
      ch->in_room = fread_number_stat( fp, &status );
      if ( !ch->in_room )
        ch->in_room = NOWHERE;
    }
    
    else if ( !str_cmp( word, "Race" ) )
    {
      i  = race_lookup( fread_string( fp, (char*)&status ) );
      
      if ( status )
        log( "Fread_char: Unknown Race." );
      else
        GET_RACE(ch) = i;
    }
    
    else if ( !str_cmp( word, "Skill" ) )
    {
      i  = fread_number_stat( fp, &status );
      sn = skill_lookup( fread_word_stat( fp, &status1 ) );
      
      if ( status || status1 )
      {
        log( "Fread_char: Error reading skill." );
        fread_to_eol( fp );
        continue;
      }
      
      if ( sn < 0 )
        log( "Fread_char: unknown skill." );
      else
        GET_SKILL(ch, sn) = i;
    }
    
    else if ( !str_cmp ( word, "Afft" ) )
    {
      
      int status;

      CREATE(paf, struct affected_type, 1);
      memset(paf, 0, sizeof( struct affected_type ));
      
      paf->type           = skill_lookup( fread_string( fp,
                                                        (char*)&status ) );
      paf->duration       = fread_number_stat( fp, &status );
      paf->modifier       = fread_number_stat( fp, &status );
      paf->location       = fread_number_stat( fp, &status );
      paf->bitvector      = fread_number_stat( fp, &status );
      paf->next           = ch->affected;
      ch->affected        = paf;
    }
    
    else
    {
Exemple #3
0
struct creature *
load_player_from_file(const char *path)
{
    struct creature *ch = NULL;
    char *txt;

    if (access(path, W_OK)) {
        errlog("Unable to open xml player file '%s': %s", path,
            strerror(errno));
        return NULL;
    }
    xmlDocPtr doc = xmlParseFile(path);
    if (!doc) {
        errlog("XML parse error while loading %s", path);
        return NULL;
    }

    xmlNodePtr root = xmlDocGetRootElement(doc);
    if (!root) {
        xmlFreeDoc(doc);
        errlog("XML file %s is empty", path);
        return NULL;
    }

    /* to save memory, only PC's -- not MOB's -- have player_specials */
    ch = make_creature(true);

    ch->player.name = (char *)xmlGetProp(root, (xmlChar *) "name");
    ch->char_specials.saved.idnum = xmlGetIntProp(root, "idnum", 0);
    set_title(ch, "");

    ch->player.short_descr = NULL;
    ch->player.long_descr = NULL;

    if (ch->points.max_mana < 100)
        ch->points.max_mana = 100;

    ch->char_specials.carry_weight = 0;
    ch->char_specials.carry_items = 0;
    ch->char_specials.worn_weight = 0;
    ch->points.armor = 100;
    ch->points.hitroll = 0;
    ch->points.damroll = 0;
    ch->player_specials->saved.speed = 0;

    // Read in the subnodes
    for (xmlNodePtr node = root->xmlChildrenNode; node; node = node->next) {
        if (xmlMatches(node->name, "points")) {
            ch->points.mana = xmlGetIntProp(node, "mana", 100);
            ch->points.max_mana = xmlGetIntProp(node, "maxmana", 100);
            ch->points.hit = xmlGetIntProp(node, "hit", 100);
            ch->points.max_hit = xmlGetIntProp(node, "maxhit", 100);
            ch->points.move = xmlGetIntProp(node, "move", 100);
            ch->points.max_move = xmlGetIntProp(node, "maxmove", 100);
        } else if (xmlMatches(node->name, "money")) {
            ch->points.gold = xmlGetIntProp(node, "gold", 0);
            ch->points.cash = xmlGetIntProp(node, "cash", 0);
            ch->points.exp = xmlGetIntProp(node, "xp", 0);
        } else if (xmlMatches(node->name, "stats")) {
            ch->player.level = xmlGetIntProp(node, "level", 0);
            ch->player.height = xmlGetIntProp(node, "height", 0);
            ch->player.weight = xmlGetIntProp(node, "weight", 0);
            GET_ALIGNMENT(ch) = xmlGetIntProp(node, "align", 0);
            /***
                Temp fix for negative weights
             ***/

            if (ch->player.weight < 0) {
                calculate_height_weight(ch);
            }

            GET_SEX(ch) = 0;
            char *sex = (char *)xmlGetProp(node, (xmlChar *) "sex");
            if (sex != NULL)
                GET_SEX(ch) = search_block(sex, genders, false);
            free(sex);

            GET_RACE(ch) = 0;
            char *race_name = (char *)xmlGetProp(node, (xmlChar *) "race");
            if (race_name != NULL) {
                struct race *race = race_by_name(race_name, true);
                if (race != NULL) {
                    GET_RACE(ch) = race->idnum;
                }
            }
            free(race_name);

        } else if (xmlMatches(node->name, "class")) {
            GET_OLD_CLASS(ch) = GET_REMORT_CLASS(ch) = GET_CLASS(ch) = -1;

            char *trade = (char *)xmlGetProp(node, (xmlChar *) "name");
            if (trade != NULL) {
                GET_CLASS(ch) = search_block(trade, class_names, false);
                free(trade);
            }

            trade = (char *)xmlGetProp(node, (xmlChar *) "remort");
            if (trade != NULL) {
                GET_REMORT_CLASS(ch) = search_block(trade, class_names, false);
                free(trade);
            }

            if (IS_CYBORG(ch)) {
                char *subclass =
                    (char *)xmlGetProp(node, (xmlChar *) "subclass");
                if (subclass != NULL) {
                    GET_OLD_CLASS(ch) = search_block(subclass,
                        borg_subchar_class_names, false);
                    free(subclass);
                }
            }

            if (GET_CLASS(ch) == CLASS_MAGE) {
                ch->player_specials->saved.mana_shield_low =
                    xmlGetLongProp(node, "manash_low", 0);
                ch->player_specials->saved.mana_shield_pct =
                    xmlGetLongProp(node, "manash_pct", 0);
            }

            GET_REMORT_GEN(ch) = xmlGetIntProp(node, "gen", 0);
            GET_TOT_DAM(ch) = xmlGetIntProp(node, "total_dam", 0);
            GET_BROKE(ch) = xmlGetIntProp(node, "broken", 0);
        } else if (xmlMatches(node->name, "time")) {
            ch->player.time.birth = xmlGetLongProp(node, "birth", 0);
            ch->player.time.death = xmlGetLongProp(node, "death", 0);
            ch->player.time.played = xmlGetLongProp(node, "played", 0);
            ch->player.time.logon = xmlGetLongProp(node, "last", 0);
        } else if (xmlMatches(node->name, "carnage")) {
            GET_PKILLS(ch) = xmlGetIntProp(node, "pkills", 0);
            GET_ARENAKILLS(ch) = xmlGetIntProp(node, "akills", 0);
            GET_MOBKILLS(ch) = xmlGetIntProp(node, "mkills", 0);
            GET_PC_DEATHS(ch) = xmlGetIntProp(node, "deaths", 0);
            RAW_REPUTATION_OF(ch) = xmlGetIntProp(node, "reputation", 0);
            GET_SEVERITY(ch) = xmlGetIntProp(node, "severity", 0);
        } else if (xmlMatches(node->name, "attr")) {
            ch->aff_abils.str = ch->real_abils.str =
                xmlGetIntProp(node, "str", 0);
            ch->aff_abils.str = ch->real_abils.str +=
                xmlGetIntProp(node, "stradd", 0) / 10;
            ch->aff_abils.intel = ch->real_abils.intel =
                xmlGetIntProp(node, "int", 0);
            ch->aff_abils.wis = ch->real_abils.wis =
                xmlGetIntProp(node, "wis", 0);
            ch->aff_abils.dex = ch->real_abils.dex =
                xmlGetIntProp(node, "dex", 0);
            ch->aff_abils.con = ch->real_abils.con =
                xmlGetIntProp(node, "con", 0);
            ch->aff_abils.cha = ch->real_abils.cha =
                xmlGetIntProp(node, "cha", 0);
        } else if (xmlMatches(node->name, "condition")) {
            GET_COND(ch, THIRST) = xmlGetIntProp(node, "thirst", 0);
            GET_COND(ch, FULL) = xmlGetIntProp(node, "hunger", 0);
            GET_COND(ch, DRUNK) = xmlGetIntProp(node, "drunk", 0);
        } else if (xmlMatches(node->name, "player")) {
            GET_WIMP_LEV(ch) = xmlGetIntProp(node, "wimpy", 0);
            GET_LIFE_POINTS(ch) = xmlGetIntProp(node, "lp", 0);
            GET_CLAN(ch) = xmlGetIntProp(node, "clan", 0);
        } else if (xmlMatches(node->name, "home")) {
            GET_HOME(ch) = xmlGetIntProp(node, "town", 0);
            GET_HOMEROOM(ch) = xmlGetIntProp(node, "homeroom", 0);
            GET_LOADROOM(ch) = xmlGetIntProp(node, "loadroom", 0);
        } else if (xmlMatches(node->name, "quest")) {
            GET_QUEST(ch) = xmlGetIntProp(node, "current", 0);
            GET_IMMORT_QP(ch) = xmlGetIntProp(node, "points", 0);
            GET_QUEST_ALLOWANCE(ch) = xmlGetIntProp(node, "allowance", 0);
        } else if (xmlMatches(node->name, "bits")) {
            char *flag = (char *)xmlGetProp(node, (xmlChar *) "flag1");
            ch->char_specials.saved.act = hex2dec(flag);
            free(flag);

            flag = (char *)xmlGetProp(node, (xmlChar *) "flag2");
            ch->player_specials->saved.plr2_bits = hex2dec(flag);
            free(flag);
        } else if (xmlMatches(node->name, "frozen")) {
            ch->player_specials->thaw_time =
                xmlGetIntProp(node, "thaw_time", 0);
            ch->player_specials->freezer_id =
                xmlGetIntProp(node, "freezer_id", 0);
        } else if (xmlMatches(node->name, "prefs")) {
            char *flag = (char *)xmlGetProp(node, (xmlChar *) "flag1");
            ch->player_specials->saved.pref = hex2dec(flag);
            free(flag);

            flag = (char *)xmlGetProp(node, (xmlChar *) "flag2");
            ch->player_specials->saved.pref2 = hex2dec(flag);
            free(flag);

            flag = (char *)xmlGetProp(node, (xmlChar *) "tongue");
            if (flag)
                GET_TONGUE(ch) = find_tongue_idx_by_name(flag);
            free(flag);
        } else if (xmlMatches(node->name, "weaponspec")) {
            int vnum = xmlGetIntProp(node, "vnum", -1);
            int level = xmlGetIntProp(node, "level", 0);
            if (vnum > 0 && level > 0) {
                for (int i = 0; i < MAX_WEAPON_SPEC; i++) {
                    if (GET_WEAP_SPEC(ch, i).level <= 0) {
                        GET_WEAP_SPEC(ch, i).vnum = vnum;
                        GET_WEAP_SPEC(ch, i).level = level;
                        break;
                    }
                }
            }
        } else if (xmlMatches(node->name, "title")) {
            char *txt;

            txt = (char *)xmlNodeGetContent(node);
            set_title(ch, txt);
            free(txt);
        } else if (xmlMatches(node->name, "affect")) {
            struct affected_type af;
            init_affect(&af);
            af.type = xmlGetIntProp(node, "type", 0);
            af.duration = xmlGetIntProp(node, "duration", 0);
            af.modifier = xmlGetIntProp(node, "modifier", 0);
            af.location = xmlGetIntProp(node, "location", 0);
            af.level = xmlGetIntProp(node, "level", 0);
            af.aff_index = xmlGetIntProp(node, "index", 0);
            af.owner = xmlGetIntProp(node, "owner", 0);
            af.next = NULL;
            char *instant = (char *)xmlGetProp(node, (xmlChar *) "instant");
            if (instant != NULL && strcmp(instant, "yes") == 0) {
                af.is_instant = 1;
            }
            free(instant);

            char *bits = (char *)xmlGetProp(node, (xmlChar *) "affbits");
            af.bitvector = hex2dec(bits);
            free(bits);

            affect_to_char(ch, &af);

        } else if (xmlMatches(node->name, "affects")) {
            // PCs shouldn't have ANY perm affects
            if (IS_NPC(ch)) {
                char *flag = (char *)xmlGetProp(node, (xmlChar *) "flag1");
                AFF_FLAGS(ch) = hex2dec(flag);
                free(flag);

                flag = (char *)xmlGetProp(node, (xmlChar *) "flag2");
                AFF2_FLAGS(ch) = hex2dec(flag);
                free(flag);

                flag = (char *)xmlGetProp(node, (xmlChar *) "flag3");
                AFF3_FLAGS(ch) = hex2dec(flag);
                free(flag);
            } else {
                AFF_FLAGS(ch) = 0;
                AFF2_FLAGS(ch) = 0;
                AFF3_FLAGS(ch) = 0;
            }

        } else if (xmlMatches(node->name, "skill")) {
            char *spellName = (char *)xmlGetProp(node, (xmlChar *) "name");
            int index = str_to_spell(spellName);
            if (index >= 0) {
                SET_SKILL(ch, index, xmlGetIntProp(node, "level", 0));
            }
            free(spellName);
        } else if (xmlMatches(node->name, "tongue")) {
            char *tongue = (char *)xmlGetProp(node, (xmlChar *) "name");
            int index = find_tongue_idx_by_name(tongue);
            if (index >= 0)
                SET_TONGUE(ch, index,
                    MIN(100, xmlGetIntProp(node, "level", 0)));
            free(tongue);
        } else if (xmlMatches(node->name, "alias")) {
            struct alias_data *alias;
            CREATE(alias, struct alias_data, 1);
            alias->type = xmlGetIntProp(node, "type", 0);
            alias->alias = (char *)xmlGetProp(node, (xmlChar *) "alias");
            alias->replacement =
                (char *)xmlGetProp(node, (xmlChar *) "replace");
            if (alias->alias == NULL || alias->replacement == NULL) {
                free(alias);
            } else {
                add_alias(ch, alias);
            }
        } else if (xmlMatches(node->name, "description")) {
            txt = (char *)xmlNodeGetContent(node);
            ch->player.description = strdup(tmp_gsub(txt, "\n", "\r\n"));
            free(txt);
        } else if (xmlMatches(node->name, "poofin")) {
            POOFIN(ch) = (char *)xmlNodeGetContent(node);
        } else if (xmlMatches(node->name, "poofout")) {
            POOFOUT(ch) = (char *)xmlNodeGetContent(node);
        } else if (xmlMatches(node->name, "immort")) {
            txt = (char *)xmlGetProp(node, (xmlChar *) "badge");
            strncpy(BADGE(ch), txt, 7);
            BADGE(ch)[7] = '\0';
            free(txt);

            GET_QLOG_LEVEL(ch) = xmlGetIntProp(node, "qlog", 0);
            GET_INVIS_LVL(ch) = xmlGetIntProp(node, "invis", 0);
        } else if (xmlMatches(node->name, "rent")) {
            char *txt;

            ch->player_specials->rentcode = xmlGetIntProp(node, "code", 0);
            ch->player_specials->rent_per_day =
                xmlGetIntProp(node, "perdiem", 0);
            ch->player_specials->rent_currency =
                xmlGetIntProp(node, "currency", 0);
            txt = (char *)xmlGetProp(node, (xmlChar *) "state");
            if (txt)
                ch->player_specials->desc_mode =
                    (enum cxn_state)search_block(txt, desc_modes, false);
            free(txt);
        } else if (xmlMatches(node->name, "recentkill")) {
            struct kill_record *kill;

            CREATE(kill, struct kill_record, 1);
            kill->vnum = xmlGetIntProp(node, "vnum", 0);
            kill->times = xmlGetIntProp(node, "times", 0);
            GET_RECENT_KILLS(ch) = g_list_prepend(GET_RECENT_KILLS(ch), kill);
        } else if (xmlMatches(node->name, "grievance")) {