*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[])
This commit is contained in:
Rob Pearce 2016-06-04 10:20:34 +10:00
parent e1edc8e14b
commit a23bedde10
6 changed files with 164 additions and 21 deletions

8
data.c
View File

@ -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);

6
defs.h
View File

@ -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;

4
flag.c
View File

@ -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) {

13
lf.c
View File

@ -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;
}
}

152
objects.c
View File

@ -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;

View File

@ -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);