From 0f90f3b76f3a8e740a1915188ff3a9933797e268 Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Thu, 9 Jun 2016 11:24:24 +1000 Subject: [PATCH] Tweak breakob code again to cope with various numbers of broken object types, not just 2. Replace all (struct)->weight with (struct)->mass. --- data.c | 4 +- defs.h | 13 +++-- lf.c | 4 +- objects.c | 167 ++++++++++++++++++++++++++++++------------------------ objects.h | 2 +- save.c | 4 +- 6 files changed, 107 insertions(+), 87 deletions(-) diff --git a/data.c b/data.c index d8debc6..65c705a 100644 --- a/data.c +++ b/data.c @@ -3186,7 +3186,7 @@ void initobjects(void) { addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some powder"); addflag(lastot->flags, F_NUMCONVERT, 100, OT_ASHLARGE, 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_STACKABLE, B_TRUE, NA, NA, ""); 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_SHRINKSTO, OT_ASH, 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_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, RR_VERYRARE, ""); diff --git a/defs.h b/defs.h index 1062c92..6e429d3 100644 --- a/defs.h +++ b/defs.h @@ -2720,6 +2720,8 @@ enum OBTYPE { #define MAXBUILDINGTYPES (11) +#define MAXBREAKOBTYPES (5) + //#define BP_NONE (-1) enum BODYPART { @@ -3038,8 +3040,9 @@ enum FLAG { // v1 = dirtype for radius F_BREAKOB, // if killed by damtype v0, change to // object 'text'. - // IMPORTANT: can only have up to 2 of these per - // damage type. + // IMPORTANT: + // - 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_NOQUALITY, // can't be masterwork / shoddy F_NOSTEAL, // this object can't be stolen, blown away, etc. @@ -5176,7 +5179,7 @@ typedef struct race_s { char *name; char *desc; struct glyph_s glyph; - float weight; + float mass; struct flagpile_s *flags; struct bodypart_s bodypart[MAXBODYPARTS]; int nbodyparts; @@ -5416,7 +5419,7 @@ typedef struct objecttype_s { struct objectclass_s *obclass; material_t *material; enum LFSIZE size; - float weight; // in kilograms + float mass; // in kilograms struct flagpile_s *flags; struct objecttype_s *next, *prev; } objecttype_t; @@ -5428,7 +5431,7 @@ typedef struct object_s { // these variables are initially // inherited from objecttype: material_t *material; - float weight; // in kilograms + float mass; // in kilograms // flags // these variables are NOT inherited char *inscription; diff --git a/lf.c b/lf.c index 02b4f4d..4fc5d48 100644 --- a/lf.c +++ b/lf.c @@ -10820,7 +10820,7 @@ enum LFSIZE getlfsize(lifeform_t *lf) { float getlfweight(lifeform_t *lf, int withobs) { float weight = 0; - weight = lf->race->weight; + weight = lf->race->mass; if (lfhasflag(lf, F_OBESE)) { weight *= 2; @@ -15841,7 +15841,7 @@ race_t *addrace(enum RACE id, char *name, float weight, int glyph, int glyphcolo assert(a->material); a->name = strdup(name); a->desc = strdup(desc); - a->weight = weight; + a->mass = weight; a->glyph.ch = glyph; a->glyph.colour = glyphcolour; a->known = B_FALSE; diff --git a/objects.c b/objects.c index d35e18c..f46c6e1 100644 --- a/objects.c +++ b/objects.c @@ -1543,7 +1543,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum // inherit props and flags from objecttype o->material = ot->material; assert(o->material); - o->weight = ot->weight; + o->mass = ot->mass; copyflags(o->flags, ot->flags, NA); // 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); } - o->weight = corpserace->weight; + o->mass = corpserace->mass; o->material = corpserace->material; // 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; - o->weight = corpserace->weight * ratio; + o->mass = corpserace->mass * ratio; // remember the race type 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); - o->weight = pctof(8, corpserace->weight); - limitf(&o->weight, 0.01, NA); + o->mass = pctof(8, corpserace->mass); + limitf(&o->mass, 0.01, NA); o->material = corpserace->material; // 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); } - o->weight = corpserace->weight / 2; + o->mass = corpserace->mass / 2; // remember the race type 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->desc = strdup(description); a->material = findmaterial(material); - a->weight = weight; + a->mass = weight; a->size = size; a->obclass = findoc(obclassid); a->flags = addflagpile(NULL, NULL); @@ -3520,7 +3520,7 @@ int confirmknowntraps(object_t *o) { void copyobprops(object_t *dst, object_t *src) { dst->material = src->material; - dst->weight = src->weight; + dst->mass = src->mass; if (src->inscription) { dst->inscription = strdup(src->inscription); } @@ -4564,16 +4564,23 @@ object_t *getbestcontainer(obpile_t *op) { return poss2[rnd(0,nposs2-1)]; } +// will ALLOCATE breakobs. remember to free afterwards +// // 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 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; - int nsmall = 0,nbig = 0; - double weight; - char bigadj[BUFLEN],smalladj[BUFLEN]; + double totmass; + //char bigadj[BUFLEN],smalladj[BUFLEN]; flag_t *retflag[MAXCANDIDATES]; int nretflags = 0,i; int found = B_FALSE; @@ -4581,46 +4588,46 @@ int getbreakob(object_t *o, char *bigobname, char *smallobname) { mid = o->material->id; dt = oblastdamtype(o); - // name to return. - strcpy(bigobname, ""); - strcpy(smallobname, ""); - // flag overrides code below found = 0; getflags(o->flags, retflag, &nretflags, F_BREAKOB, F_NONE); + *nbreakobs = 0; for (i = 0; i < nretflags; i++) { f = retflag[i]; if (f && (f->val[0] == dt)) { - if (found == 0) { - strcpy(bigobname, f->text); - } else if (found == 1) { - strcpy(smallobname, f->text); - } else { + breakobname[*nbreakobs] = strdup(f->text); + strcpy(adj[*nbreakobs], ""); + + if (++(*nbreakobs) >= MAXBREAKOBTYPES) { msg("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; } + // determine breakobs based on materials + // adjectives - strcpy(bigadj, ""); - strcpy(smalladj, ""); switch (mid) { case MT_WOOD: if (ismeleedam(dt) || (dt == DT_EXPLOSIVE)) { - bigoid = OT_WOODPLANK; - smalloid = OT_WOODSHARD; + breakoid[0] = OT_WOODPLANK; + breakoid[1] = OT_WOODSHARD; + (*nbreakobs) = 2; } else { switch (dt) { case DT_FIRE: case DT_HEAT: case DT_ACID: - bigoid = OT_ASH; - smalloid = OT_ASH; + breakoid[0] = OT_ASHHUGE; + breakoid[1] = OT_ASHLARGE; + breakoid[2] = OT_ASH; + (*nbreakobs) = 3; break; default: break; } @@ -4628,16 +4635,18 @@ int getbreakob(object_t *o, char *bigobname, char *smallobname) { break; case MT_GLASS: if (ismeleedam(dt) || (dt == DT_EXPLOSIVE)) { - bigoid = OT_BROKENGLASS; - smalloid = OT_BROKENGLASS; + breakoid[0] = OT_WOODPLANK; + (*nbreakobs) = 1; break; } else { switch (dt) { case DT_FIRE: case DT_HEAT: case DT_ACID: - bigoid = OT_ASH; - smalloid = OT_ASH; + breakoid[0] = OT_ASHHUGE; + breakoid[1] = OT_ASHLARGE; + breakoid[2] = OT_ASH; + (*nbreakobs) = 3; break; default: break; } @@ -4645,15 +4654,16 @@ int getbreakob(object_t *o, char *bigobname, char *smallobname) { break; case MT_ICE: if (ismeleedam(dt) || (dt == DT_EXPLOSIVE)) { - bigoid = OT_ICECHUNK; - smalloid = OT_ICECHUNK; + breakoid[0] = OT_ICECHUNK; + (*nbreakobs) = 1; break; } else { switch (dt) { case DT_FIRE: case DT_HEAT: - bigoid = OT_PUDDLEWATERL; - smalloid = OT_PUDDLEWATER; + breakoid[0] = OT_PUDDLEWATERL; + breakoid[1] = OT_PUDDLEWATER; + (*nbreakobs) = 2; break; default: break; } @@ -4662,8 +4672,10 @@ int getbreakob(object_t *o, char *bigobname, char *smallobname) { case MT_FLESH: switch (dt) { case DT_FIRE: - bigoid = OT_ASH; - smalloid = OT_ASH; + breakoid[0] = OT_ASHHUGE; + breakoid[1] = OT_ASHLARGE; + breakoid[2] = OT_ASH; + (*nbreakobs) = 3; break; default: break; } @@ -4671,28 +4683,31 @@ int getbreakob(object_t *o, char *bigobname, char *smallobname) { default: break; } - big = findot(bigoid); - small = findot(smalloid); - - // 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); + for (i = 0; i < *nbreakobs; i++) { + breakob[i] = findot(breakoid[i]); } - if (nbig) { - sprintf(bigobname, "%d %s",nbig,big->name); - } - if (nsmall) { - sprintf(smallobname, "%d %s",nsmall,small->name); + // now find out how many obejcts of each type make up the wight. + totmass = getobmass(o); + for (i = 0; i < *nbreakobs; i++) { + float thismass; + 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_FALSE; @@ -7049,7 +7064,7 @@ float getobweight(object_t *o) { if (hasflag(o->flags, F_DEEPWATER)) { weight = 75 * getobdepth(o, NULL); } else { - weight = o->weight; + weight = o->mass; } // has its material been changed? @@ -8596,7 +8611,7 @@ int isoperable(object_t *o) { // parent objecttype? int isplainob(object_t *o) { 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->blessed != B_UNCURSED) return B_FALSE; if (isblessknown(o)) return B_FALSE; @@ -10075,23 +10090,25 @@ void obdie(object_t *o) { if (o->pile->where) { int minbones,maxbones; char bonestr[BUFLEN]; - minbones = o->weight / 10; - maxbones = o->weight / 5; + minbones = o->mass / 10; + maxbones = o->mass / 5; if (minbones <= 0) minbones = 1; if (maxbones <= minbones) maxbones = 2; snprintf(bonestr, BUFLEN, "%d-%d bones",minbones,maxbones); addob(o->pile, bonestr); } } else { - char bigbreak[BUFLEN],smallbreak[BUFLEN]; - // maybe create broken object based on material - getbreakob(o, bigbreak, smallbreak); + char *breakobname[MAXBREAKOBTYPES]; + int nbreakobs,i; - if (strlen(smallbreak)) { - addob(loc->obpile, smallbreak); - } - if (strlen(bigbreak)) { - addob(loc->obpile, bigbreak); + // maybe create broken object based on material + getbreakob(o, breakobname, &nbreakobs); + + for (i = 0; i < nbreakobs; i++) { + if (breakobname[i]) { + addob(loc->obpile, breakobname[i]); + free(breakobname[i]); + } } } } @@ -10657,7 +10674,7 @@ int obproduceslight(object_t *o) { int obpropsmatch(object_t *a, object_t *b) { if (a->type != b->type) 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; // only really need to check one of them, because at this point // 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; meat = addob(o->pile, "chunk of roast meat"); // purposely don't use getweight! - meat->weight = o->weight; + meat->mass = o->mass; copyflag(meat->flags, o->flags, F_CORPSEOF); ff = hasflag(o->flags, F_OBHP); if (ff) { @@ -17086,7 +17103,7 @@ void timeeffectsob(object_t *o) { if (newob) { int cansee; // make the weight match. - newob->weight = o->weight; + newob->mass = o->mass; // announce it? cansee = B_FALSE; 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) { flag_t *f, *f2; // inherit weight - newob->weight = trappedob->weight; + newob->mass = trappedob->mass; // inherit hp from original ob f = hasflag(trappedob->flags, F_OBHP); if (f) { diff --git a/objects.h b/objects.h index 2d875e3..7593f97 100644 --- a/objects.h +++ b/objects.h @@ -80,7 +80,7 @@ void genhiddennames(void); enum LFSIZE getarmoursize(object_t *o); enum RARITY getavgrarity(flagpile_t *fp); 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 getcharges(object_t *o); enum SKILL getclassloreskill(enum OBCLASS oc); diff --git a/save.c b/save.c index d1a0779..8aa5a86 100644 --- a/save.c +++ b/save.c @@ -571,7 +571,7 @@ int loadob(FILE *f, obpile_t *op, long *id) { } o->material = mat; - fscanf(f, "weight:%f\n",&o->weight); + fscanf(f, "weight:%f\n",&o->mass); fgets(buf, BUFLEN, f); // inscription 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, "type:%d\n",o->type->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, "letter:%c\n",o->letter); fprintf(f, "bless:%d\n",o->blessed);