Tweak breakob code again to cope with various numbers of broken object types, not just 2.

Replace all (struct)->weight with (struct)->mass.
This commit is contained in:
Rob Pearce 2016-06-09 11:24:24 +10:00
parent 74b0e9841f
commit 0f90f3b76f
6 changed files with 107 additions and 87 deletions

4
data.c
View File

@ -3186,7 +3186,7 @@ void initobjects(void) {
addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some powder"); addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some powder");
addflag(lastot->flags, F_NUMCONVERT, 100, OT_ASHLARGE, NA, NULL); addflag(lastot->flags, F_NUMCONVERT, 100, OT_ASHLARGE, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_DUSTCLOUD, VT_OB, NA, NULL); addflag(lastot->flags, F_GROWSTO, OT_DUSTCLOUD, VT_OB, NA, NULL);
addot(OT_ASHLARGE, "large pile of ash", "A large pile of ash.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); addot(OT_ASHLARGE, "large pile of ash", "A large pile of ash.", MT_STONE, 2, OC_ROCK, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_DARKGREY, ',', NA, NULL); addflag(lastot->flags, F_GLYPH, C_DARKGREY, ',', NA, NULL);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, RR_RARE, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, RR_RARE, "");
@ -3197,7 +3197,7 @@ void initobjects(void) {
addflag(lastot->flags, F_NUMCONVERT, 100, OT_ASHHUGE, NA, NULL); addflag(lastot->flags, F_NUMCONVERT, 100, OT_ASHHUGE, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_ASH, VT_OB, NA, NULL); addflag(lastot->flags, F_SHRINKSTO, OT_ASH, VT_OB, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_DUSTCLOUD, VT_OB, NA, NULL); addflag(lastot->flags, F_GROWSTO, OT_DUSTCLOUD, VT_OB, NA, NULL);
addot(OT_ASHHUGE, "huge pile of ash", "A huge pile of ash.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); addot(OT_ASHHUGE, "huge pile of ash", "A huge pile of ash.", MT_STONE, 20, OC_ROCK, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_DARKGREY, ',', NA, NULL); addflag(lastot->flags, F_GLYPH, C_DARKGREY, ',', NA, NULL);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, RR_VERYRARE, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, RR_VERYRARE, "");

13
defs.h
View File

@ -2720,6 +2720,8 @@ enum OBTYPE {
#define MAXBUILDINGTYPES (11) #define MAXBUILDINGTYPES (11)
#define MAXBREAKOBTYPES (5)
//#define BP_NONE (-1) //#define BP_NONE (-1)
enum BODYPART { enum BODYPART {
@ -3038,8 +3040,9 @@ enum FLAG {
// v1 = dirtype for radius // v1 = dirtype for radius
F_BREAKOB, // if killed by damtype v0, change to F_BREAKOB, // if killed by damtype v0, change to
// object 'text'. // object 'text'.
// IMPORTANT: can only have up to 2 of these per // IMPORTANT:
// damage type. // - breakobs with high mass MUST be listed first.
// - can only have up to MAXBREAKOBTYPES of these per damage type.
F_NOBLESS, // can't be blessed or cursed F_NOBLESS, // can't be blessed or cursed
F_NOQUALITY, // can't be masterwork / shoddy F_NOQUALITY, // can't be masterwork / shoddy
F_NOSTEAL, // this object can't be stolen, blown away, etc. F_NOSTEAL, // this object can't be stolen, blown away, etc.
@ -5176,7 +5179,7 @@ typedef struct race_s {
char *name; char *name;
char *desc; char *desc;
struct glyph_s glyph; struct glyph_s glyph;
float weight; float mass;
struct flagpile_s *flags; struct flagpile_s *flags;
struct bodypart_s bodypart[MAXBODYPARTS]; struct bodypart_s bodypart[MAXBODYPARTS];
int nbodyparts; int nbodyparts;
@ -5416,7 +5419,7 @@ typedef struct objecttype_s {
struct objectclass_s *obclass; struct objectclass_s *obclass;
material_t *material; material_t *material;
enum LFSIZE size; enum LFSIZE size;
float weight; // in kilograms float mass; // in kilograms
struct flagpile_s *flags; struct flagpile_s *flags;
struct objecttype_s *next, *prev; struct objecttype_s *next, *prev;
} objecttype_t; } objecttype_t;
@ -5428,7 +5431,7 @@ typedef struct object_s {
// these variables are initially // these variables are initially
// inherited from objecttype: // inherited from objecttype:
material_t *material; material_t *material;
float weight; // in kilograms float mass; // in kilograms
// flags // flags
// these variables are NOT inherited // these variables are NOT inherited
char *inscription; char *inscription;

4
lf.c
View File

@ -10820,7 +10820,7 @@ enum LFSIZE getlfsize(lifeform_t *lf) {
float getlfweight(lifeform_t *lf, int withobs) { float getlfweight(lifeform_t *lf, int withobs) {
float weight = 0; float weight = 0;
weight = lf->race->weight; weight = lf->race->mass;
if (lfhasflag(lf, F_OBESE)) { if (lfhasflag(lf, F_OBESE)) {
weight *= 2; weight *= 2;
@ -15841,7 +15841,7 @@ race_t *addrace(enum RACE id, char *name, float weight, int glyph, int glyphcolo
assert(a->material); assert(a->material);
a->name = strdup(name); a->name = strdup(name);
a->desc = strdup(desc); a->desc = strdup(desc);
a->weight = weight; a->mass = weight;
a->glyph.ch = glyph; a->glyph.ch = glyph;
a->glyph.colour = glyphcolour; a->glyph.colour = glyphcolour;
a->known = B_FALSE; a->known = B_FALSE;

167
objects.c
View File

@ -1543,7 +1543,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
// inherit props and flags from objecttype // inherit props and flags from objecttype
o->material = ot->material; o->material = ot->material;
assert(o->material); assert(o->material);
o->weight = ot->weight; o->mass = ot->mass;
copyflags(o->flags, ot->flags, NA); copyflags(o->flags, ot->flags, NA);
// don't want certain objecttype only flags... // don't want certain objecttype only flags...
@ -2078,7 +2078,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
corpserace = getrandomcorpserace(NULL, wantarmsize); corpserace = getrandomcorpserace(NULL, wantarmsize);
} }
o->weight = corpserace->weight; o->mass = corpserace->mass;
o->material = corpserace->material; o->material = corpserace->material;
// remember the race type // remember the race type
@ -2149,7 +2149,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
ratio = o->material->weightrating / corpserace->material->weightrating; ratio = o->material->weightrating / corpserace->material->weightrating;
o->weight = corpserace->weight * ratio; o->mass = corpserace->mass * ratio;
// remember the race type // remember the race type
addflag(o->flags, F_CORPSEOF, corpserace->id, 1, NA, NULL); addflag(o->flags, F_CORPSEOF, corpserace->id, 1, NA, NULL);
@ -2182,8 +2182,8 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
assert(corpserace); assert(corpserace);
o->weight = pctof(8, corpserace->weight); o->mass = pctof(8, corpserace->mass);
limitf(&o->weight, 0.01, NA); limitf(&o->mass, 0.01, NA);
o->material = corpserace->material; o->material = corpserace->material;
// remember the race type // remember the race type
@ -2212,7 +2212,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
if (corpserace->id != corpserace->baseid) corpserace = findrace(corpserace->baseid); if (corpserace->id != corpserace->baseid) corpserace = findrace(corpserace->baseid);
} }
o->weight = corpserace->weight / 2; o->mass = corpserace->mass / 2;
// remember the race type // remember the race type
addflag(o->flags, F_CORPSEOF, corpserace->id, 1, NA, NULL); addflag(o->flags, F_CORPSEOF, corpserace->id, 1, NA, NULL);
@ -2672,7 +2672,7 @@ objecttype_t *addot(enum OBTYPE id, char *name, char *description, int material,
a->name = strdup(name); a->name = strdup(name);
a->desc = strdup(description); a->desc = strdup(description);
a->material = findmaterial(material); a->material = findmaterial(material);
a->weight = weight; a->mass = weight;
a->size = size; a->size = size;
a->obclass = findoc(obclassid); a->obclass = findoc(obclassid);
a->flags = addflagpile(NULL, NULL); a->flags = addflagpile(NULL, NULL);
@ -3520,7 +3520,7 @@ int confirmknowntraps(object_t *o) {
void copyobprops(object_t *dst, object_t *src) { void copyobprops(object_t *dst, object_t *src) {
dst->material = src->material; dst->material = src->material;
dst->weight = src->weight; dst->mass = src->mass;
if (src->inscription) { if (src->inscription) {
dst->inscription = strdup(src->inscription); dst->inscription = strdup(src->inscription);
} }
@ -4564,16 +4564,23 @@ object_t *getbestcontainer(obpile_t *op) {
return poss2[rnd(0,nposs2-1)]; return poss2[rnd(0,nposs2-1)];
} }
// will ALLOCATE breakobs. remember to free afterwards
//
// returns TRUE if an break obejct was found. // returns TRUE if an break obejct was found.
int getbreakob(object_t *o, char *bigobname, char *smallobname) { int getbreakob(object_t *o, char **breakobname, int *nbreakobs) {
enum MATERIAL mid; enum MATERIAL mid;
enum DAMTYPE dt; enum DAMTYPE dt;
enum OBTYPE bigoid = OT_NONE,smalloid = OT_NONE;
objecttype_t *big = NULL,*small = NULL; enum OBTYPE breakoid[MAXBREAKOBTYPES];
objecttype_t *breakob[MAXBREAKOBTYPES];
char adj[BUFLEN][MAXBREAKOBTYPES];
int nobs[MAXBREAKOBTYPES];
//enum OBTYPE bigoid = OT_NONE,smalloid = OT_NONE;
//objecttype_t *big = NULL,*small = NULL;
flag_t *f; flag_t *f;
int nsmall = 0,nbig = 0; double totmass;
double weight; //char bigadj[BUFLEN],smalladj[BUFLEN];
char bigadj[BUFLEN],smalladj[BUFLEN];
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags = 0,i; int nretflags = 0,i;
int found = B_FALSE; int found = B_FALSE;
@ -4581,46 +4588,46 @@ int getbreakob(object_t *o, char *bigobname, char *smallobname) {
mid = o->material->id; mid = o->material->id;
dt = oblastdamtype(o); dt = oblastdamtype(o);
// name to return.
strcpy(bigobname, "");
strcpy(smallobname, "");
// flag overrides code below // flag overrides code below
found = 0; found = 0;
getflags(o->flags, retflag, &nretflags, F_BREAKOB, F_NONE); getflags(o->flags, retflag, &nretflags, F_BREAKOB, F_NONE);
*nbreakobs = 0;
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
if (f && (f->val[0] == dt)) { if (f && (f->val[0] == dt)) {
if (found == 0) { breakobname[*nbreakobs] = strdup(f->text);
strcpy(bigobname, f->text); strcpy(adj[*nbreakobs], "");
} else if (found == 1) {
strcpy(smallobname, f->text); if (++(*nbreakobs) >= MAXBREAKOBTYPES) {
} else {
msg("ERROR - too many F_BREAKOB flags in %s",o->type->name); msg("ERROR - too many F_BREAKOB flags in %s",o->type->name);
dblog("ERROR - too many F_BREAKOB flags in %s",o->type->name); dblog("ERROR - too many F_BREAKOB flags in %s",o->type->name);
} raise(SIGINT);
found++;
} }
} }
if (found) { }
if (*nbreakobs) {
// flags have told us what the name is
return B_TRUE; return B_TRUE;
} }
// determine breakobs based on materials
// adjectives // adjectives
strcpy(bigadj, "");
strcpy(smalladj, "");
switch (mid) { switch (mid) {
case MT_WOOD: case MT_WOOD:
if (ismeleedam(dt) || (dt == DT_EXPLOSIVE)) { if (ismeleedam(dt) || (dt == DT_EXPLOSIVE)) {
bigoid = OT_WOODPLANK; breakoid[0] = OT_WOODPLANK;
smalloid = OT_WOODSHARD; breakoid[1] = OT_WOODSHARD;
(*nbreakobs) = 2;
} else { } else {
switch (dt) { switch (dt) {
case DT_FIRE: case DT_FIRE:
case DT_HEAT: case DT_HEAT:
case DT_ACID: case DT_ACID:
bigoid = OT_ASH; breakoid[0] = OT_ASHHUGE;
smalloid = OT_ASH; breakoid[1] = OT_ASHLARGE;
breakoid[2] = OT_ASH;
(*nbreakobs) = 3;
break; break;
default: break; default: break;
} }
@ -4628,16 +4635,18 @@ int getbreakob(object_t *o, char *bigobname, char *smallobname) {
break; break;
case MT_GLASS: case MT_GLASS:
if (ismeleedam(dt) || (dt == DT_EXPLOSIVE)) { if (ismeleedam(dt) || (dt == DT_EXPLOSIVE)) {
bigoid = OT_BROKENGLASS; breakoid[0] = OT_WOODPLANK;
smalloid = OT_BROKENGLASS; (*nbreakobs) = 1;
break; break;
} else { } else {
switch (dt) { switch (dt) {
case DT_FIRE: case DT_FIRE:
case DT_HEAT: case DT_HEAT:
case DT_ACID: case DT_ACID:
bigoid = OT_ASH; breakoid[0] = OT_ASHHUGE;
smalloid = OT_ASH; breakoid[1] = OT_ASHLARGE;
breakoid[2] = OT_ASH;
(*nbreakobs) = 3;
break; break;
default: break; default: break;
} }
@ -4645,15 +4654,16 @@ int getbreakob(object_t *o, char *bigobname, char *smallobname) {
break; break;
case MT_ICE: case MT_ICE:
if (ismeleedam(dt) || (dt == DT_EXPLOSIVE)) { if (ismeleedam(dt) || (dt == DT_EXPLOSIVE)) {
bigoid = OT_ICECHUNK; breakoid[0] = OT_ICECHUNK;
smalloid = OT_ICECHUNK; (*nbreakobs) = 1;
break; break;
} else { } else {
switch (dt) { switch (dt) {
case DT_FIRE: case DT_FIRE:
case DT_HEAT: case DT_HEAT:
bigoid = OT_PUDDLEWATERL; breakoid[0] = OT_PUDDLEWATERL;
smalloid = OT_PUDDLEWATER; breakoid[1] = OT_PUDDLEWATER;
(*nbreakobs) = 2;
break; break;
default: break; default: break;
} }
@ -4662,8 +4672,10 @@ int getbreakob(object_t *o, char *bigobname, char *smallobname) {
case MT_FLESH: case MT_FLESH:
switch (dt) { switch (dt) {
case DT_FIRE: case DT_FIRE:
bigoid = OT_ASH; breakoid[0] = OT_ASHHUGE;
smalloid = OT_ASH; breakoid[1] = OT_ASHLARGE;
breakoid[2] = OT_ASH;
(*nbreakobs) = 3;
break; break;
default: break; default: break;
} }
@ -4671,28 +4683,31 @@ int getbreakob(object_t *o, char *bigobname, char *smallobname) {
default: break; default: break;
} }
big = findot(bigoid); for (i = 0; i < *nbreakobs; i++) {
small = findot(smalloid); breakob[i] = findot(breakoid[i]);
// now find out how many big obejcts make up the wight.
weight = getobmass(o) / 3;
if (big) {
nbig = weight / big->weight;
weight -= (nbig*big->weight);
}
if (small){
nsmall = weight / small->weight;
weight -= (nsmall*small->weight);
} }
if (nbig) { // now find out how many obejcts of each type make up the wight.
sprintf(bigobname, "%d %s",nbig,big->name); totmass = getobmass(o);
} for (i = 0; i < *nbreakobs; i++) {
if (nsmall) { float thismass;
sprintf(smallobname, "%d %s",nsmall,small->name); thismass = breakob[i]->mass;
nobs[i] = totmass / thismass;
totmass -= (nobs[i] * thismass);
} }
if (strlen(bigobname) || strlen(smallobname)) {
for (i = 0; i < *nbreakobs; i++) {
if (nobs[i] > 0) {
char buf[BUFLEN];
sprintf(buf, "%d %s", nobs[i], breakob[i]->name);
breakobname[i] = strdup(buf);
} else {
breakobname[i] = NULL;
}
}
if (*nbreakobs) {
return B_TRUE; return B_TRUE;
} }
return B_FALSE; return B_FALSE;
@ -7049,7 +7064,7 @@ float getobweight(object_t *o) {
if (hasflag(o->flags, F_DEEPWATER)) { if (hasflag(o->flags, F_DEEPWATER)) {
weight = 75 * getobdepth(o, NULL); weight = 75 * getobdepth(o, NULL);
} else { } else {
weight = o->weight; weight = o->mass;
} }
// has its material been changed? // has its material been changed?
@ -8596,7 +8611,7 @@ int isoperable(object_t *o) {
// parent objecttype? // parent objecttype?
int isplainob(object_t *o) { int isplainob(object_t *o) {
if (o->material != o->type->material) return B_FALSE; if (o->material != o->type->material) return B_FALSE;
if (o->weight != o->type->weight) return B_FALSE; if (o->mass != o->type->mass) return B_FALSE;
if (o->inscription) return B_FALSE; if (o->inscription) return B_FALSE;
if (o->blessed != B_UNCURSED) return B_FALSE; if (o->blessed != B_UNCURSED) return B_FALSE;
if (isblessknown(o)) return B_FALSE; if (isblessknown(o)) return B_FALSE;
@ -10075,23 +10090,25 @@ void obdie(object_t *o) {
if (o->pile->where) { if (o->pile->where) {
int minbones,maxbones; int minbones,maxbones;
char bonestr[BUFLEN]; char bonestr[BUFLEN];
minbones = o->weight / 10; minbones = o->mass / 10;
maxbones = o->weight / 5; maxbones = o->mass / 5;
if (minbones <= 0) minbones = 1; if (minbones <= 0) minbones = 1;
if (maxbones <= minbones) maxbones = 2; if (maxbones <= minbones) maxbones = 2;
snprintf(bonestr, BUFLEN, "%d-%d bones",minbones,maxbones); snprintf(bonestr, BUFLEN, "%d-%d bones",minbones,maxbones);
addob(o->pile, bonestr); addob(o->pile, bonestr);
} }
} else { } else {
char bigbreak[BUFLEN],smallbreak[BUFLEN]; char *breakobname[MAXBREAKOBTYPES];
// maybe create broken object based on material int nbreakobs,i;
getbreakob(o, bigbreak, smallbreak);
if (strlen(smallbreak)) { // maybe create broken object based on material
addob(loc->obpile, smallbreak); getbreakob(o, breakobname, &nbreakobs);
for (i = 0; i < nbreakobs; i++) {
if (breakobname[i]) {
addob(loc->obpile, breakobname[i]);
free(breakobname[i]);
} }
if (strlen(bigbreak)) {
addob(loc->obpile, bigbreak);
} }
} }
} }
@ -10657,7 +10674,7 @@ int obproduceslight(object_t *o) {
int obpropsmatch(object_t *a, object_t *b) { int obpropsmatch(object_t *a, object_t *b) {
if (a->type != b->type) return B_FALSE; if (a->type != b->type) return B_FALSE;
if (a->material != b->material) return B_FALSE; if (a->material != b->material) return B_FALSE;
if (a->weight != b->weight) return B_FALSE; if (a->mass != b->mass) return B_FALSE;
if (a->inscription || b->inscription) return B_FALSE; if (a->inscription || b->inscription) return B_FALSE;
// only really need to check one of them, because at this point // only really need to check one of them, because at this point
// we know they are of the same type. // we know they are of the same type.
@ -15193,7 +15210,7 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce, lif
flag_t *ff; flag_t *ff;
meat = addob(o->pile, "chunk of roast meat"); meat = addob(o->pile, "chunk of roast meat");
// purposely don't use getweight! // purposely don't use getweight!
meat->weight = o->weight; meat->mass = o->mass;
copyflag(meat->flags, o->flags, F_CORPSEOF); copyflag(meat->flags, o->flags, F_CORPSEOF);
ff = hasflag(o->flags, F_OBHP); ff = hasflag(o->flags, F_OBHP);
if (ff) { if (ff) {
@ -17086,7 +17103,7 @@ void timeeffectsob(object_t *o) {
if (newob) { if (newob) {
int cansee; int cansee;
// make the weight match. // make the weight match.
newob->weight = o->weight; newob->mass = o->mass;
// announce it? // announce it?
cansee = B_FALSE; cansee = B_FALSE;
if (location && haslos(player, location)) { if (location && haslos(player, location)) {
@ -17319,7 +17336,7 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c, object_t *trapped
if (newob) { if (newob) {
flag_t *f, *f2; flag_t *f, *f2;
// inherit weight // inherit weight
newob->weight = trappedob->weight; newob->mass = trappedob->mass;
// inherit hp from original ob // inherit hp from original ob
f = hasflag(trappedob->flags, F_OBHP); f = hasflag(trappedob->flags, F_OBHP);
if (f) { if (f) {

View File

@ -80,7 +80,7 @@ void genhiddennames(void);
enum LFSIZE getarmoursize(object_t *o); enum LFSIZE getarmoursize(object_t *o);
enum RARITY getavgrarity(flagpile_t *fp); enum RARITY getavgrarity(flagpile_t *fp);
object_t *getbestcontainer(obpile_t *op); object_t *getbestcontainer(obpile_t *op);
int getbreakob(object_t *o, char *bigobname, char *smallobname); int getbreakob(object_t *o, char **breakobname, int *nbreakobtypes);
int getchargeinfo(object_t *o, int *cur, int *max); int getchargeinfo(object_t *o, int *cur, int *max);
int getcharges(object_t *o); int getcharges(object_t *o);
enum SKILL getclassloreskill(enum OBCLASS oc); enum SKILL getclassloreskill(enum OBCLASS oc);

4
save.c
View File

@ -571,7 +571,7 @@ int loadob(FILE *f, obpile_t *op, long *id) {
} }
o->material = mat; o->material = mat;
fscanf(f, "weight:%f\n",&o->weight); fscanf(f, "weight:%f\n",&o->mass);
fgets(buf, BUFLEN, f); // inscription fgets(buf, BUFLEN, f); // inscription
buf[strlen(buf)-1] = '\0'; // strip newline buf[strlen(buf)-1] = '\0'; // strip newline
@ -1157,7 +1157,7 @@ int saveob(FILE *f, object_t *o) {
fprintf(f, "id:%ld\n",o->id); fprintf(f, "id:%ld\n",o->id);
fprintf(f, "type:%d\n",o->type->id); fprintf(f, "type:%d\n",o->type->id);
fprintf(f, "material:%d\n",o->material->id); fprintf(f, "material:%d\n",o->material->id);
fprintf(f, "weight:%f\n",o->weight); fprintf(f, "weight:%f\n",o->mass);
fprintf(f, "inscr:%s\n",o->inscription ? o->inscription : "^^^"); fprintf(f, "inscr:%s\n",o->inscription ? o->inscription : "^^^");
fprintf(f, "letter:%c\n",o->letter); fprintf(f, "letter:%c\n",o->letter);
fprintf(f, "bless:%d\n",o->blessed); fprintf(f, "bless:%d\n",o->blessed);