Every new version breaks old saves. That might be necessary to add new features, but it's not cool when you lose your Grade-A badass founder. So I wrote something to export/import a liberal's stats into a human-readable .liberal file. Sample output:
[BIOGRAPHICAL INFORMATION]
Given Name: Miguel Stone
Code Name: Ammons Hart
Date of Birth: 10-16-1984
Place of Origin: Philadelphia, PA
Occupation: Political Activist
[ATTRIBUTES]
Strength: 4
Intelligence: 7
Wisdom: 1
Agility: 5
Health: 6
Charisma: 7
Heart: 13
Juice: 645
[SKILLS]
Pistol: 3.66
Persuasion: 14.00
Psychology: 17.00
Law: 2.00
Security: 4.83
Disguise: 9.47
Tailoring: 0.49
Driving: 3.76
Writing: 3.04
Art: 2.15
Religion: 1.00
Business: 0.14
Stealth: 1.00
Theft: 0.64
Seduction: 2.21
Leadership: 8.78
Tactics: 0.45
[WOUNDS]
I want input from other people, particularly on how this should fit in to the game. I'm seeing a few different options:
Exported liberals can stay in the old game, be treated as though they went to start a LCS chapter in a different city, or something else entirely.
Imported liberals can be used only to start a new game (as founder), be answering personal ads ("Polyamorous 22yo liberal seeking partner to help fight the man"), or something.
Thoughts? Is there even any demand for this feature?
Also, I thought I had the train(...) thing figured out but apparently I don't. If anybody could correct it ( cr.train(sk,x); ), that'd be great.
Also, importing the wounds was more work than it's worth until it's decided how (if?) this fits in to the game.
void exportliberal(creaturest &e)
{
FILE *h;
char str[200];
strcpy(str,e.name);
strcat(str,".liberal");
h=LCSOpenFile(str, "w+", LCSIO_PRE_HOME);
fprintf(h,"[BIOGRAPHICAL INFORMATION]\n");
fprintf(h,"Given Name: %s\n",e.propername);
fprintf(h,"Code Name: %s\n",e.name);
fprintf(h,"Date of Birth: %02d-%02d-%4d\n",e.birthday_month,e.birthday_day,year-e.age);
fprintf(h,"Place of Origin: %s\n",lcityname);
getrecruitcreature(str,e.type);
fprintf(h,"Occupation: %s\n",str);
fprintf(h,"\n[ATTRIBUTES]\n");
fprintf(h,"Strength: %d\n",e.att[ATTRIBUTE_STRENGTH]);
fprintf(h,"Intelligence: %d\n",e.att[ATTRIBUTE_INTELLIGENCE]);
fprintf(h,"Wisdom: %d\n",e.att[ATTRIBUTE_WISDOM]);
fprintf(h,"Agility: %d\n",e.att[ATTRIBUTE_AGILITY]);
fprintf(h,"Health: %d\n",e.att[ATTRIBUTE_HEALTH]);
fprintf(h,"Charisma: %d\n",e.att[ATTRIBUTE_CHARISMA]);
fprintf(h,"Heart: %d\n",e.att[ATTRIBUTE_HEART]);
fprintf(h,"Juice: %d\n",e.juice);
fprintf(h,"\n[SKILLS]\n");
for(int sk=0; sk<SKILLNUM; sk++)
{
if(e.skill[sk]>0 || e.get_skill_ip(sk)>0)
{
getskill(str,sk);
fprintf(h,"%s: %d.%02d\n",str,e.skill[sk],
(e.get_skill_ip(sk)*100)/(100+(10*e.skill[sk])));
}
}
fprintf(h,"\n[WOUNDS]\n");
if((e.wound[BODYPART_LEG_RIGHT] & WOUND_NASTYOFF)||
(e.wound[BODYPART_LEG_RIGHT] & WOUND_CLEANOFF)) fprintf(h,"Missing: right leg.\n");
if((e.wound[BODYPART_LEG_LEFT] & WOUND_NASTYOFF)||
(e.wound[BODYPART_LEG_LEFT] & WOUND_CLEANOFF)) fprintf(h,str,"Missing: left leg.\n");
if((e.wound[BODYPART_ARM_RIGHT] & WOUND_NASTYOFF)||
(e.wound[BODYPART_ARM_RIGHT] & WOUND_CLEANOFF)) fprintf(h,"Missing: right arm.\n");
if((e.wound[BODYPART_ARM_LEFT] & WOUND_NASTYOFF)||
(e.wound[BODYPART_ARM_LEFT] & WOUND_CLEANOFF)) fprintf(h,"Missing: left arm.\n");
if(e.special[SPECIALWOUND_RIGHTEYE]!=1) fprintf(h,"Missing: right eye.\n");
if(e.special[SPECIALWOUND_LEFTEYE]!=1) fprintf(h,"Missing: left eye.\n");
if(e.special[SPECIALWOUND_NOSE]!=1) fprintf(h,"Missing: nose.\n");
if(e.special[SPECIALWOUND_TONGUE]!=1) fprintf(h,"Missing: tongue.\n");
if(e.special[SPECIALWOUND_TEETH]!=TOOTHNUM) fprintf(h,"Missing: %d teeth.\n",TOOTHNUM-e.special[SPECIALWOUND_TEETH]);
LCSCloseFile(h);
}
void importliberal(char *codename)
{
FILE *h;
char str[200], r1[200];
char *eoftest, *r2, *val;
int type = 0;
strcat(codename, ".liberal");
h=LCSOpenFile(codename, "r", LCSIO_PRE_HOME);
if(h==NULL)
{
//this liberal cannot be found, possibly as a result of Conservative conspiracy
}
else
{
creaturest cr;
cr.creatureinit();
cr.type=CREATURE_POLITICALACTIVIST;
eoftest=fgets(r1,200,h);
while(1)
{
while(memcmp(r1,"[",1)!=0 && memcmp(r1,"\n",1)!=0)
{
r2 = strtok(r1,":");
val = strtok(NULL,":");
val[strcspn(val,"\n")]='\0';//strip off the newline character
if(val!=NULL)
{
switch(type)//type: 1=bio, 2=atts, 3=skills, 4=wounds
{
case 1:
if(strcmp(r2,"Given Name")==0)
{
strcpy(cr.propername,&val[1]);
break;
}
else if(strcmp(r2,"Code Name")==0)
{
strcpy(cr.name,&val[1]);
break;
}
else if(strcmp(r2,"Date of Birth")==0)
{
int m,d,y;
sscanf(val,"%02d-%02d-%4d",&m,&d,&y);
cr.birthday_month=m;
cr.birthday_day=d;
cr.age=year-y;
break;
}
else if(strcmp(r2,"Place of Origin")==0)
{
break;
}
else if(strcmp(r2,"Occupation")==0)
{
for(int i=0; i<CREATURENUM; i++)
{
getrecruitcreature(str,i);
if(strcmp(&val[1],str)==0) cr.type=i;
}
break;
} else break;
case 2:
int i;
if(strcmp(r2,"Strength")==0)
{
sscanf(val,"%d",&i);
cr.att[ATTRIBUTE_STRENGTH]=i;
break;
} else if(strcmp(r2,"Intelligence")==0)
{
sscanf(val,"%d",&i);
cr.att[ATTRIBUTE_INTELLIGENCE]=i;
break;
} else if(strcmp(r2,"Wisdom")==0)
{
sscanf(val,"%d",&i);
cr.att[ATTRIBUTE_WISDOM]=i;
break;
} else if(strcmp(r2,"Agility")==0)
{
sscanf(val,"%d",&i);
cr.att[ATTRIBUTE_AGILITY]=i;
break;
} else if(strcmp(r2,"Health")==0)
{
sscanf(val,"%d",&i);
cr.att[ATTRIBUTE_HEALTH]=i;
break;
} else if(strcmp(r2,"Charisma")==0)
{
sscanf(val,"%d",&i);
cr.att[ATTRIBUTE_CHARISMA]=i;
break;
} else if(strcmp(r2,"Heart")==0)
{
sscanf(val,"%d",&i);
cr.att[ATTRIBUTE_HEART]=i;
break;
} else if(strcmp(r2,"Juice")==0)
{
sscanf(val,"%d",&i);
cr.juice=i;
break;
} else break;
case 3:
int j,k;
for(int sk=0; sk<SKILLNUM; sk++)
{
getskill(str,sk);
if(strcmp(r2,str)==0)
{
sscanf(val,"%d.%02d",&j,&k);
cr.skill[sk]=j;
int x = 6*(100+10*j)*k/(100*maxskill(sk,cr,true));
cr.train(sk,x);//this should be right but isn't! help!
}
}
break;
case 4:
break;
default:
break;
}
}
eoftest=fgets(r1,200,h);
if(eoftest==NULL) break;
}
if(strcmp(r1,"[BIOGRAPHICAL INFORMATION]\n")==0) type=1;
if(strcmp(r1,"[ATTRIBUTES]\n")==0) type=2;
if(strcmp(r1,"[SKILLS]\n")==0) type=3;
if(strcmp(r1,"[WOUNDS]\n")==0) type=4;
eoftest=fgets(r1,200,h);
if(eoftest==NULL) break;
}
//other stuff to finalize the liberal depending on where this ends up
LCSCloseFile(h);
}
}