/
circle30bpl9/lib/
circle30bpl9/lib/etc/
circle30bpl9/lib/misc/
circle30bpl9/lib/plrobjs/
circle30bpl9/lib/world/
circle30bpl9/lib/world/shp/
/*

play2to3.c - CircleMUD v2.2-to-v3.0 player file converter

June 12th, 1995

This is a quick&dirty hack to convert a player file from CircleMUD v2.2
to CircleMUD v3.0.  As far as I know it works and it should be portable,
but I have only compiled and tested it under Linux 1.1.59.

Edward Almasy
almasy@axis.com

*/

#include <stdio.h>
#include <time.h>
#include <sys/types.h>

typedef signed char         sbyte;
typedef unsigned char       ubyte;
typedef signed short int    sh_int;
typedef unsigned short int  ush_int;
typedef char                bool;
typedef char                byte;
typedef sh_int              room_num;

#define THREE_MAX_NAME_LENGTH   20  
#define THREE_MAX_PWD_LENGTH    10  
#define THREE_MAX_TITLE_LENGTH  80  
#define THREE_HOST_LENGTH       30  
#define THREE_EXDSCR_LENGTH     240 
#define THREE_MAX_TONGUE        3   
#define THREE_MAX_SKILLS        200 
#define THREE_MAX_AFFECT        32  

struct THREE_char_ability_data {
   sbyte str;
   sbyte str_add;      /* 000 - 100 if strength 18             */
   sbyte intel;
   sbyte wis;
   sbyte dex;
   sbyte con;
   sbyte cha;
};

struct THREE_char_point_data {
   sh_int 	mana;
   sh_int 	max_mana;   	    /* Max mana for PC/NPC                     */
   sh_int 	hit;
   sh_int 	max_hit;    	    /* Max hit for PC/NPC                      */
   sh_int 	move;
   sh_int 	max_move;   	    /* Max move for PC/NPC                     */
   sh_int   armor;      	    /* Internal -100..100, external -10..10 AC */
   int      gold;       	    /* Money carried                           */
   int      bank_gold;  	    /* Gold the char has in a bank account     */
   int      exp;        	    /* The experience of the player            */
   sbyte    hitroll;    	    /* Any bonus or penalty to the hit roll    */
   sbyte    damroll;            /* Any bonus or penalty to the damage roll */
};

struct THREE_char_special_data_saved {
   int      alignment;          /* +-1000 for alignments                */
   long     idnum;              /* player's idnum; -1 for mobiles       */
   long     act;                /* act flag for NPC's; player flag for PC's */
   long     affected_by;        /* Bitvector for spells/skills affected by */
   sh_int   apply_saving_throw[5]; /* Saving throw (Bonuses)            */
};

struct THREE_player_special_data_saved {
   byte     skills[THREE_MAX_SKILLS+1]; /* array of skills plus skill 0 */
   byte     spells_to_learn;    /* How many can you learn yet this level*/
   bool     talks[THREE_MAX_TONGUE]; /* PC s Tongues 0 for NPC          */
   int      wimp_level;         /* Below this # of hit points, flee!    */
   byte     freeze_level;       /* Level of god who froze char, if any  */
   sh_int   invis_level;        /* level of invisibility                */
   room_num load_room;          /* Which room to place char in          */
   long     pref;               /* preference flags for PC's.           */
   ubyte    bad_pws;            /* number of bad password attemps       */
   sbyte    conditions[3];      /* Drunk, full, thirsty                 */
   ubyte    spare0;
   ubyte 	spare1;
   ubyte 	spare2;
   ubyte 	spare3;
   ubyte 	spare4;
   ubyte 	spare5;
   int 		spare6;
   int 		spare7;
   int 		spare8;
   int 		spare9;
   int 		spare10;
   int 		spare11;
   int 		spare12;
   int 		spare13;
   int 		spare14;
   int 		spare15;
   int 		spare16;
   long 	spare17;
   long 	spare18;
   long 	spare19;
   long 	spare20;
   long 	spare21;
};

/* An affect structure.  Used in char_file_u *DO*NOT*CHANGE* */
struct THREE_affected_type {
   sh_int   type;               /* The type of spell that caused this      */
   sh_int   duration;      		/* For how long its effects will last      */
   sbyte    modifier;           /* This is added to apropriate ability     */
   byte     location;      		/* Tells which ability to change(APPLY_XXX)*/
   long     bitvector;     		/* Tells which bits to set (AFF_XXX)       */

   struct THREE_affected_type *next;
};

struct THREE_char_file_u {
   char     name[THREE_MAX_NAME_LENGTH+1];
   char     description[THREE_EXDSCR_LENGTH];
   char     title[THREE_MAX_TITLE_LENGTH+1];
   byte     sex;
   byte     class;
   byte     level;
   sh_int   hometown;
   time_t   birth;              /* Time of birth of character     */
   int      played;             /* Number of secs played in total */
   ubyte    weight;
   ubyte    height;
   char     pwd[THREE_MAX_PWD_LENGTH+1];    /* character's password */

   struct THREE_char_special_data_saved     char_specials_saved;
   struct THREE_player_special_data_saved   player_specials_saved;
   struct THREE_char_ability_data           abilities;
   struct THREE_char_point_data             points;
   struct THREE_affected_type               affected[THREE_MAX_AFFECT];

   time_t   last_logon;           /* Time (in secs) of last logon */
   char     host[THREE_HOST_LENGTH+1];      /* host of last logon */
};

#define TWO_MAX_PWD_LENGTH  10
#define TWO_HOST_LEN        30
#define TWO_MAX_TOUNGE      3
#define TWO_MAX_SKILLS      128
#define TWO_MAX_AFFECT      32

struct TWO_char_ability_data {
   sbyte str;
   sbyte str_add;      /* 000 - 100 if strength 18             */
   sbyte intel;
   sbyte wis;
   sbyte dex;
   sbyte con;
};

struct TWO_char_point_data {
   sh_int   mana;
   sh_int   max_mana;     /* Max move for PC/NPC                     */
   sh_int   hit;
   sh_int   max_hit;      /* Max hit for PC/NPC                      */
   sh_int   move;
   sh_int   max_move;     /* Max move for PC/NPC                     */
   sh_int   armor;        /* Internal -100..100, external -10..10 AC */
   int      gold;         /* Money carried                           */
   int      bank_gold;    /* Gold the char has in a bank account     */
   int      exp;          /* The experience of the player            */
   sbyte    hitroll;      /* Any bonus or penalty to the hit roll    */
   sbyte    damroll;      /* Any bonus or penalty to the damage roll */
};

struct TWO_char_special2_data {
   long     idnum;                 /* player's idnum                       */
   sh_int   load_room;             /* Which room to place char in          */
   byte     spells_to_learn;       /* How many can you learn yet this level*/
   int      alignment;             /* +-1000 for alignments                */
   long     act;                   /* act flag for NPC's; player flag for PC's */
   long     pref;                  /* preference flags for PC's.           */
   int      wimp_level;            /* Below this # of hit points, flee!    */
   byte     freeze_level;          /* Level of god who froze char, if any  */
   ubyte    bad_pws;               /* number of bad password attemps       */
   sh_int   apply_saving_throw[5]; /* Saving throw (Bonuses)              */
   sbyte    conditions[3];         /* Drunk full etc.                      */
   ubyte    spare0;
   ubyte    spare1;
   ubyte    spare2;
   ubyte    spare3;
   ubyte    spare4;
   ubyte    spare5;
   ubyte    spare6;
   ubyte    spare7;
   ubyte    spare8;
   ubyte    spare9;
   ubyte    spare10;
   ubyte    spare11;
   long     spare12;
   long     spare13;
   long     spare14;
   long     spare15;
   long     spare16;
   long     spare17;
   long     spare18;
   long     spare19;
   long     spare20;
   long     spare21;
};

/* Used in CHAR_FILE_U *DO*NOT*CHANGE* */
struct TWO_affected_type {
   sbyte    type;          /* The type of spell that caused this      */
   sh_int   duration;      /* For how long its effects will last      */
   sbyte    modifier;      /* This is added to apropriate ability     */
   byte     location;      /* Tells which ability to change(APPLY_XXX)*/
   long     bitvector;     /* Tells which bits to set (AFF_XXX)       */
   struct TWO_affected_type *next;
};

struct TWO_char_file_u {
   byte                         sex;
   byte                         class;
   byte                         level;
   time_t                       birth;  /* Time of birth of character     */
   int                          played;    /* Number of secs played in total */
   ubyte                        weight;
   ubyte                        height;
   char                         title[80];
   sh_int                       hometown;
   char                         description[240];
   bool                         talks[TWO_MAX_TOUNGE];
   struct TWO_char_ability_data abilities;
   struct TWO_char_point_data   points;
   byte                         skills[TWO_MAX_SKILLS];
   struct TWO_affected_type     affected[TWO_MAX_AFFECT];
   struct TWO_char_special2_data specials2;
   time_t                       last_logon;  /* Time (in secs) of last logon */
   char                         host[TWO_HOST_LEN+1];   /* host of last logon */
   char                         name[20];
   char                         pwd[TWO_MAX_PWD_LENGTH+1];
};

int main(
    int argc,
    char *argv[])
{
    struct TWO_char_file_u      stTwo;
    struct THREE_char_file_u    stThree;
    FILE                       *ptTwoHndl;
    FILE                       *ptThreeHndl;
    int                         iIndex;
    char                       *apcClassAbbrev[] = { "Mu", "Cl", "Th", "Wa" };
    int                         aiSkillMappings[] = { 138, 133, 139, 131, 135, 134, 132, 137 };

    if (argc < 3)
    {
        printf("usage: play2to3 [old 2.2 player file] [new 3.0 player file]\n");
        exit(1);
    }

    ptTwoHndl = fopen(argv[1], "rb");
    if (ptTwoHndl == NULL)
    {
        printf("unable to open source file \"%s\"\n", argv[1]);
        exit(1);
    }

    ptThreeHndl = fopen(argv[2], "wb");
    if (ptThreeHndl == NULL)
    {
        printf("unable to open destination file \"%s\"\n", argv[2]);
        exit(1);
    }

    while (!feof(ptTwoHndl))
    {
        fread(&stTwo, sizeof(struct TWO_char_file_u), 1, ptTwoHndl);

        strcpy(stThree.name,        stTwo.name);
        strcpy(stThree.description, stTwo.description);
        strcpy(stThree.title,       stTwo.title);
        stThree.sex               = stTwo.sex;
        stThree.class             = stTwo.class - 1;
        stThree.level             = stTwo.level;
        stThree.hometown          = stTwo.hometown;
        stThree.birth             = stTwo.birth;
        stThree.played            = stTwo.played;
        stThree.weight            = stTwo.weight;
        stThree.height            = stTwo.height;
        strcpy(stThree.pwd,         stTwo.pwd);

        stThree.char_specials_saved.alignment = stTwo.specials2.alignment;
        stThree.char_specials_saved.idnum = stTwo.specials2.idnum;
        stThree.char_specials_saved.act = stTwo.specials2.act;
        stThree.char_specials_saved.affected_by = 0;    /* ??? */
        for (iIndex = 0;  iIndex < 5;  iIndex++)
            stThree.char_specials_saved.apply_saving_throw[iIndex] = 
                    stTwo.specials2.apply_saving_throw[iIndex];

        for (iIndex = 0;  iIndex < THREE_MAX_SKILLS;  iIndex++)
            stThree.player_specials_saved.skills[iIndex] = 0;
        for (iIndex = 0;  iIndex < 53;  iIndex++)
            if (iIndex > 44)
            {
                stThree.player_specials_saved.skills[
                        aiSkillMappings[iIndex - 45]] = stTwo.skills[iIndex];
            }
            else
                stThree.player_specials_saved.skills[iIndex] = 
                        stTwo.skills[iIndex];
        stThree.player_specials_saved.spells_to_learn = 
                stTwo.specials2.spells_to_learn;
        for (iIndex = 0;  iIndex < THREE_MAX_TONGUE;  iIndex++)
            stThree.player_specials_saved.talks[iIndex] = stTwo.talks[iIndex];
        stThree.player_specials_saved.wimp_level = stTwo.specials2.wimp_level;
        stThree.player_specials_saved.freeze_level = 
                stTwo.specials2.freeze_level;
        stThree.player_specials_saved.invis_level = 0;
        stThree.player_specials_saved.load_room = stTwo.specials2.load_room;
        stThree.player_specials_saved.pref = stTwo.specials2.pref;
        stThree.player_specials_saved.bad_pws = stTwo.specials2.bad_pws;
        for (iIndex = 0;  iIndex < 3;  iIndex++)
            stThree.player_specials_saved.conditions[iIndex] = 
                    stTwo.specials2.conditions[iIndex];
        stThree.player_specials_saved.spare0 = 0;
        stThree.player_specials_saved.spare1 = 0;
        stThree.player_specials_saved.spare2 = 0;
        stThree.player_specials_saved.spare3 = 0;
        stThree.player_specials_saved.spare4 = 0;
        stThree.player_specials_saved.spare5 = 0;
        stThree.player_specials_saved.spare6 = 0;
        stThree.player_specials_saved.spare7 = 0;
        stThree.player_specials_saved.spare8 = 0;
        stThree.player_specials_saved.spare9 = 0;
        stThree.player_specials_saved.spare10 = 0;
        stThree.player_specials_saved.spare11 = 0;
        stThree.player_specials_saved.spare12 = 0;
        stThree.player_specials_saved.spare13 = 0;
        stThree.player_specials_saved.spare14 = 0;
        stThree.player_specials_saved.spare15 = 0;
        stThree.player_specials_saved.spare16 = 0;
        stThree.player_specials_saved.spare17 = 0;
        stThree.player_specials_saved.spare18 = 0;
        stThree.player_specials_saved.spare19 = 0;
        stThree.player_specials_saved.spare20 = 0;
        stThree.player_specials_saved.spare21 = 0;

        stThree.abilities.str = stTwo.abilities.str;
        stThree.abilities.str_add = stTwo.abilities.str_add;
        stThree.abilities.intel = stTwo.abilities.intel;
        stThree.abilities.wis = stTwo.abilities.wis;
        stThree.abilities.dex = stTwo.abilities.dex;
        stThree.abilities.con = stTwo.abilities.con;
        stThree.abilities.cha = 12;

        stThree.points.mana = stTwo.points.mana;
        stThree.points.max_mana = stTwo.points.max_mana;
        stThree.points.hit = stTwo.points.hit;
        stThree.points.max_hit = stTwo.points.max_hit;
        stThree.points.move = stTwo.points.move;
        stThree.points.max_move = stTwo.points.max_move;
        stThree.points.armor = stTwo.points.armor;
        stThree.points.gold = stTwo.points.gold;
        stThree.points.bank_gold = stTwo.points.bank_gold;
        stThree.points.exp = stTwo.points.exp;
        stThree.points.hitroll = stTwo.points.hitroll;
        stThree.points.damroll = stTwo.points.damroll;

        for (iIndex = 0;  iIndex < TWO_MAX_AFFECT;  iIndex++)
        {
            stThree.affected[iIndex].type = stTwo.affected[iIndex].type;
            stThree.affected[iIndex].duration = stTwo.affected[iIndex].duration;
            stThree.affected[iIndex].modifier = stTwo.affected[iIndex].modifier;
            stThree.affected[iIndex].location = stTwo.affected[iIndex].location;
            stThree.affected[iIndex].bitvector = stTwo.affected[iIndex].bitvector;
            stThree.affected[iIndex].next = NULL;
        }

        stThree.last_logon        = stTwo.last_logon;
        strcpy(stThree.host, stTwo.host);

        printf("[%2d %s] %s %s\n", 
                stThree.level, apcClassAbbrev[stThree.class], stThree.name, stThree.title);

        fwrite(&stThree, sizeof(struct THREE_char_file_u), 1, ptThreeHndl);
    }

    fclose(ptThreeHndl);
    fclose(ptTwoHndl);
}