From a23bedde10f2ee184c9a0b473394d25e63ffa3e4 Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Sat, 4 Jun 2016 10:20:34 +1000 Subject: [PATCH] *When using a towel, make it able to dry off objects on the ground. *When using a towel, make it wet based on how much you dry off. *Create Water description should specify that water is created on the ground. *when creating "a wet xxx", make its wetness time be the maximum. *fixed bug where F_WET obmods would not show up after the v1 timer value changed (added flags->obmodignore[]) --- data.c | 8 +-- defs.h | 6 +++ flag.c | 4 ++ lf.c | 13 +++-- objects.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++++----- objects.h | 2 + 6 files changed, 164 insertions(+), 21 deletions(-) diff --git a/data.c b/data.c index 257992c..a921119 100644 --- a/data.c +++ b/data.c @@ -1838,11 +1838,11 @@ void initobjects(void) { addflag_real(lastobmod->flags, F_HITCONFER, F_POISONED, SC_POISON, 150, "15-30", PERMENANT, B_KNOWN, -1); addflag_real(lastobmod->flags, F_HITCONFERVALS, P_VENOM, 1, NA, NULL, PERMENANT, B_KNOWN, -1); addobmod(OM_WET1,"damp"); - addflag_real(lastobmod->flags, F_WET, W_DAMP, NA, NA, NULL, PERMENANT, B_KNOWN, -1); + f = addflag_real(lastobmod->flags, F_WET, W_DAMP, TM_WETTIME, NA, NULL, PERMENANT, B_KNOWN, -1); f->obmodignoreval[1] = B_TRUE; // v1 can change addobmod(OM_WET2,"wet"); - addflag_real(lastobmod->flags, F_WET, W_WET, NA, NA, NULL, PERMENANT, B_KNOWN, -1); + f = addflag_real(lastobmod->flags, F_WET, W_WET, TM_WETTIME, NA, NULL, PERMENANT, B_KNOWN, -1); f->obmodignoreval[1] = B_TRUE; // v1 can change addobmod(OM_WET3,"soaked"); - addflag_real(lastobmod->flags, F_WET, W_SOAKED, NA, NA, NULL, PERMENANT, B_KNOWN, -1); + f = addflag_real(lastobmod->flags, F_WET, W_SOAKED, TM_WETTIME, NA, NULL, PERMENANT, B_KNOWN, -1); f->obmodignoreval[1] = B_TRUE; // v1 can change addobmod(OM_RUSTY1,"rusty"); addflag_real(lastobmod->flags, F_RUSTED, R_RUSTY, NA, NA, NULL, PERMENANT, B_KNOWN, -1); addobmod(OM_RUSTY2,"very rusty"); @@ -5656,7 +5656,7 @@ void initobjects(void) { addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); - addot(OT_S_CREATEWATER, "create water", "Creates a large pool of shallow water.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addot(OT_S_CREATEWATER, "create water", "Creates a large pool of shallow water on the ground.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines the size of the pool."); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); diff --git a/defs.h b/defs.h index 3866910..94a862c 100644 --- a/defs.h +++ b/defs.h @@ -110,6 +110,9 @@ #define B_MAYBE (-2) #define B_ONEOF (-3) +#define B_EQUIPPEDONLY (-1) +#define B_ANY (0) + #define B_FROMCRIT (-1) #define B_NOCRIT (0) @@ -320,6 +323,7 @@ #define MIN_TEMPERATURE -10 #define MAX_TEMPERATURE 45 + // askobject options /* #define AO_NONE 0 @@ -3322,6 +3326,7 @@ enum FLAG { // damage. F_BRUISED, // object is bruised (nutrition penalty) F_WET, // object is wet + // v0 = enum WETNESS. v1 = how long left until it reduces to the next dryness level F_RUSTED, // object is rusty // v0 = enum RUSTINESS. // object mods/effects @@ -5279,6 +5284,7 @@ typedef struct flag_s { enum FLAG id; int nvals; int val[3]; + int obmodignoreval[3]; char *text; struct altflagval_s *altval; // don't need to save this. enum FLAGCONDITION condition; diff --git a/flag.c b/flag.c index 039ce22..4d882d7 100644 --- a/flag.c +++ b/flag.c @@ -278,6 +278,10 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, f->val[i] = NA; } + for (i = 0; i < 3; i++) { + f->obmodignoreval[i] = B_FALSE; + } + f->val[0] = val1; f->nvals = 1; if (val2 != NA) { diff --git a/lf.c b/lf.c index a2ee84f..46c4820 100644 --- a/lf.c +++ b/lf.c @@ -9414,17 +9414,20 @@ int getnextshortcut(lifeform_t *lf) { // use 1=10 instead of 0=9, so that '0' is last. for (slotnum = 1; slotnum <= (LASTSHORTCUT+1); slotnum++) { int found = B_FALSE; + int slottouse; + if (slotnum == 10) slottouse = 0; + else slottouse = slotnum; + // technically this is faster than using hasflagval() for (i = 0; i < nretflags; i++) { - if (retflag[i]->val[0] == slotnum) { + if (retflag[i]->val[0] == slottouse) { found = B_TRUE; break; } } if (!found) { // this slot is available - if (slotnum == 10) slotnum = 0; - return slotnum; + return slottouse; } } @@ -16814,7 +16817,9 @@ void autoshortcut(lifeform_t *lf, enum OBTYPE spellid, int startslot) { // if we don't already have a shortcut for this... if (!lfhasflagval(lf, F_SHORTCUT, NA, NA, NA, ot->name)) { addflag(lf->flags, F_SHORTCUT, min, NA, NA, ot->name); + dblog("added shortcut #%d = %s", min, ot->name); min = getnextshortcut(lf); + dblog(" next shortcut is %d", min); if (min == NA) return; } } @@ -16823,6 +16828,8 @@ void autoshortcut(lifeform_t *lf, enum OBTYPE spellid, int startslot) { if (f->val[0] == spellid) { // set to lowest possible shortcut addflag(lf->flags, F_SHORTCUT, min, NA, NA, ot->name); + dblog("added shortcut #%d = %s", min, ot->name); + dblog(" returning"); return; } } diff --git a/objects.c b/objects.c index 254c785..6225504 100644 --- a/objects.c +++ b/objects.c @@ -3681,6 +3681,19 @@ int curseob(object_t *o) { return rv; } +int countpilewetness(obpile_t *op, int equippedonly, object_t *exclude) { + object_t *oo; + int count = 0; + + for (oo = op->first ;oo ; oo = oo->next) { + if (oo == exclude) continue; + if (!equippedonly || isequipped(oo)) { + count += getobwetness(oo); + } + } + return count; +} + void damageallobs(object_t *srcob, obpile_t *op, int howmuch, int damtype, lifeform_t *srclf) { object_t *o, *nexto; int nhurt = 0; @@ -6978,7 +6991,6 @@ float getobunitweight(object_t *o) { } } - return weight; } @@ -7621,6 +7633,27 @@ enum BODYPART getweildloc(object_t *o, lifeform_t *lf, enum BODYPART *otherloc, return weildloc; } + +int getobwetness(object_t *o) { + flag_t *wetflag; + int count = 0; + wetflag = hasflag(o->flags, F_WET); + if (wetflag) { + // towel will get slightly wetter. + switch (wetflag->val[0]) { + case W_DAMP: count += 1; + break; + case W_WET: count += TM_WETTIME; // 10 damp objects = 1 wet object + break; + case W_SOAKED: count += (TM_WETTIME*TM_WETTIME); // 10 wet objects = 1 soaked object + break; + default: + break; + } + } + return count; +} + int hasedibleob(obpile_t *op) { object_t *o; for (o = op->first ; o ; o = o->next) { @@ -7706,7 +7739,12 @@ int hasobmod(object_t *o, obmod_t *om) { flag_t *omf; int found = B_TRUE; for (omf = om->flags->first ; omf ; omf = omf->next){ - if (!hasflagval(o->flags, omf->id, omf->val[0], omf->val[1], omf->val[2], NULL)) { + int val[3],i; + for (i = 0; i < 3; i++) { + if (omf->obmodignoreval[i]) val[i] = NA; + else val[i] = omf->val[i]; + } + if (!hasflagval(o->flags, omf->id, val[0], val[1], val[2], NULL)) { found = B_FALSE; break; } @@ -12168,20 +12206,107 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { } } } else if (o->type->id == OT_TOWEL) { - object_t *oo; - if (isplayer(lf)) { - msg("You dry yourself off with %s.", obname); - } else if (cansee(player, lf)) { - char lfname[BUFLEN]; - getlfname(lf, lfname); - msg("%s dries itself off with %s.", lfname, obname); + int count = 0; + enum WETNESS howwet = W_DRY; + char ch = 'n'; + + if (hasflag(o->flags, F_WET)) { + if (isplayer(lf)) { + msg("Your %s is too wet to be effective.", noprefix(obname)); + } + // fail + return B_TRUE; } - // make objects dry - for (oo = lf->pack->first ;oo ; oo = oo->next) { - if (isequipped(oo)) { - killflagsofid(oo->flags, F_WET); + + // what will we dry? + if (isplayer(lf)) { + if (hasobwithflag(lf->cell->obpile, F_WET)) { + char buf[BUFLEN]; + snprintf(buf, BUFLEN, "There are wet objects here. Use your %s to dry one?", noprefix(obname)); + + ch = askchar(buf, "yn","n", B_TRUE, B_FALSE); } } + + if (ch == 'y') { + object_t *oo; + + condset_t cs; + initcondv(&cs, CC_HASFLAG, B_TRUE, F_WET, + CC_NONE); + oo = askobject(lf->cell->obpile, "Dry off which object", "There are no wet objects here.", NULL, '\0', &cs, B_TRUE); + if (oo) { + char obname2[BUFLEN]; + getobname(oo, obname2, oo->amt); + + count = getobwetness(oo); + if (!count) { + if (isplayer(lf)) msg("%s doesn't need drying!", obname2); + return B_TRUE; + } + + // announce + if (isplayer(lf)) { + msg("You dry off %s with %s.", obname2, obname); + } else if (cansee(player, lf)) { + char lfname[BUFLEN]; + getlfname(lf, lfname); + msg("%s dries off %s with %s.", lfname, obname2, obname); + } + + // make it dry + killflagsofid(oo->flags, F_WET); + + } else { + if (isplayer(lf)) msg("Cancelled."); + return B_TRUE; + } + } else { + // equipped objects? (all at once) + count = countpilewetness(lf->pack, B_EQUIPPEDONLY, o); + if (count) { + object_t *oo,*nextoo; + // announce + if (isplayer(lf)) { + msg("You dry yourself off with %s.", obname); + } else if (cansee(player, lf)) { + char lfname[BUFLEN]; + getlfname(lf, lfname); + msg("%s dries itself off with %s.", lfname, obname); + } + + // actually make objects dry + for (oo = lf->pack->first ;oo ; oo = nextoo) { + nextoo = oo->next; + if (oo == o) continue; + if (isequipped(oo)) { + killflagsofid(oo->flags, F_WET); + } + } + } else { + // announce + if (isplayer(lf)) { + msg("You're already dry."); + } + return B_TRUE; + } + } + + // make the towel wet + count /= TM_WETTIME; + + if (count >= (TM_WETTIME * TM_WETTIME)) { + howwet = W_SOAKED; + } else if (count >= TM_WETTIME) { + howwet = W_WET; + } else if (count > 0) { + howwet = W_DAMP; + } else { + howwet = W_DRY; + } + + makewet(o, howwet); + taketime(lf, getactspeed(lf)); } else if (hasflag(o->flags, F_SHOP)) { shop(lf, o); @@ -17961,7 +18086,6 @@ int getflamingobs(obpile_t *op, object_t **retob, int *nretobs) { return num; } - // populate retob[] with ingredents for the given recipe, taken from the given object pile int getingredients(obpile_t *op, recipe_t *rec, object_t **retob, int *retcount, int *retconsume, int *nretobs, int promptformulti) { int i; diff --git a/objects.h b/objects.h index 1ed12e7..eb26986 100644 --- a/objects.h +++ b/objects.h @@ -53,6 +53,7 @@ int countobswithflag(obpile_t *op, enum FLAG flagid); int countobswithflagval(obpile_t *op, enum FLAG flagid, int val0, int val1, int val2, char *text); int countnoncosmeticobs(obpile_t *op, int onlyifknown, int includetrails); int curseob(object_t *o); +int countpilewetness(obpile_t *op, int equippedonly, object_t *exclude); void damageallobs(object_t *srcob, obpile_t *op, int howmuch, int damtype, lifeform_t *srclf); void dodecay(object_t *o); int doobdieconvert(object_t *o, int wantannounce); @@ -171,6 +172,7 @@ enum SKILLLEVEL gettechlevel(enum OBTYPE oid); int getthrowdam(object_t *o); char *gettopobname(cell_t *c, char *retbuf); enum BODYPART getweildloc(object_t *o, lifeform_t *lf, enum BODYPART *otherloc, int *twohanded); +int getobwetness(object_t *o); int hasedibleob(obpile_t *op); object_t *hasequippedobid(obpile_t *op, enum OBTYPE oid); object_t *hasequippedobidon(obpile_t *op, enum OBTYPE oid, enum BODYPART bp);