From 2f80d6ba0547282f88176a1b2c758b9760c4f7b5 Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Thu, 3 Jan 2013 04:39:34 +0000 Subject: [PATCH] - [+] rewrite gettrrange() - [+] reduce chances of dulling weapon from hitting things - [+] crash during save. other save/load fixes. - [+] simplify xp value calculation. - [+] fixes for checks to see whether cells are diggable using "dig" spell. - [+] fix shop closed bug - "we are closed" text not appearing. - [+] sound code mods - should no longer ever hear "muffled slithering" (since slithering should be too soft to travel through walls) - [+] undead will no longer try to heal via resting (since they can't). --- ai.c | 14 +++++-- attack.c | 4 +- data.c | 7 +++- data/hiscores.db | Bin 17408 -> 17408 bytes god.c | 5 +++ io.c | 38 ++++++++++++------ lf.c | 88 +++++++++++++++++++++++++++++----------- map.c | 8 ++-- move.c | 4 +- nexus.c | 102 +++++++++++++++++++++++++++++++---------------- objects.c | 20 +++++++--- objects.h | 1 + save.c | 25 ++++++++---- shops.c | 10 +++-- shops.h | 2 +- spell.c | 13 +++--- 16 files changed, 234 insertions(+), 107 deletions(-) diff --git a/ai.c b/ai.c index 8eb3c68..95eb40f 100644 --- a/ai.c +++ b/ai.c @@ -941,7 +941,7 @@ int aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim getradiuscells(lf->cell, 1, DT_COMPASS, B_TRUE, LOF_DONTNEED, B_FALSE, cell, &ncells, 0); for (i = 0; i < ncells; i++) { if (cell[i]->type->solid && - (isdiggable(cell[i], OT_NONE) && + (isdiggable(cell[i], OT_S_DIG) && getcelldist(cell[i], victim->cell) == 1)) { poss[nposs++] = cell[i]; break; @@ -1408,7 +1408,7 @@ int ai_bored(lifeform_t *lf, lifeform_t *master, int icanattack) { } } // need to heal? - if (needstorest(lf, NULL) && !hasflag(lf->flags, F_RAGE)) { + if (needstorest(lf, NULL) && !hasflag(lf->flags, F_RAGE) && !lfhasflag(lf, F_NORESTHEAL)) { enum ERROR why; if (safetorest(lf, &why) || (why == E_TOOSOON)) { if (db) dblog(".oO { resting to heal }"); @@ -2889,7 +2889,7 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG getradiuscells(lf->cell, 1, DT_COMPASS, B_TRUE, LOF_DONTNEED, B_FALSE, cell, &ncells, 0); for (i = 0; i < ncells; i++) { if (cell[i]->type->solid && - (cell[i]->type->material->id == MT_STONE) && + isdiggable(cell[i], OT_S_DIG) && getcelldist(cell[i], victim->cell) == 1) { ok = B_TRUE; break; @@ -3085,6 +3085,14 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG specificcheckok = B_FALSE; } } + if (ot->id == OT_A_DISARM) { + if (purpose == F_AICASTTOFLEE) { + // check our own cell + if (!isdiggable(lf->cell, OT_S_DIG)) { + specificcheckok = B_FALSE; + } + } + } if (ot->id == OT_A_DISARM) { if (!getweapon(victim)) { specificcheckok = B_FALSE; diff --git a/attack.c b/attack.c index 385996f..30f88e3 100644 --- a/attack.c +++ b/attack.c @@ -1991,7 +1991,7 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) { if (wep && (ndam > 0)) { if (wepdullable(wep)) { // weapon gets duller - if (rnd(1,2)) makeduller(wep, 1); + makedullermaybe(wep, 1); } } } @@ -2180,7 +2180,7 @@ int attackwall(lifeform_t *lf, cell_t *c, object_t *wep, flag_t *damflag) { if (wep && (ndam > 0)) { if (wepdullable(wep)) { // weapon gets duller - if (rnd(1,2)) makeduller(wep, 1); + makedullermaybe(wep, 1); } } diff --git a/data.c b/data.c index db8803b..c1dd588 100644 --- a/data.c +++ b/data.c @@ -4961,6 +4961,11 @@ void initobjects(void) { addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SPECIAL, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); + addflag(lastot->flags, F_DIGCELLMAT, MT_DIRT, NA, NA, NULL); + addflag(lastot->flags, F_DIGCELLMAT, MT_STONE, NA, NA, NULL); + addflag(lastot->flags, F_DIGCELLMAT, MT_WOOD, NA, NA, NULL); + addflag(lastot->flags, F_DIGCELLMAT, MT_ICE, NA, NA, NULL); + addflag(lastot->flags, F_DIGCELLMAT, MT_PLANT, NA, NA, NULL); addot(OT_S_ENTANGLE, "entangle", "Causes magical vines to hold enemies.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines the strength of the vines."); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); @@ -8581,7 +8586,7 @@ void initobjects(void) { addflag(lastot->flags, F_VALUE, 300, NA, NA, NULL); addot(OT_AMU_PROT_MAJ, "amulet of major protection", "Enhances its wearer's Armour Rating by 10.", MT_METAL, 0.3, OC_AMULET, SZ_TINY); - addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL); + addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_ARBOOST, 10, NA, NULL); addflag(lastot->flags, F_VALUE, 600, NA, NA, NULL); diff --git a/data/hiscores.db b/data/hiscores.db index 2547cef4cc5a0a6a7fa10223b481d582bb3d4a6d..11d1b503acf97c4f7e6d13b2aeacdbd39f61d4c2 100644 GIT binary patch delta 195 zcmZqZU~K4MoFL8Uy;0@`J99Xb?__q4m26DmOhHV(o40XHXXIyLW?&2l5n&)AbaM>X z3Q;~*rXmLBP0UHmLQDskiZ&J|Fvflags, F_HASBRAND)) { char obname[BUFLEN]; + brand_t *br; flag_t *f; getobname(wep,obname,1); // announce msg("Your %s vibrates, and you suddenly thirst for vengeance!", noprefix(obname)); f = addflag(wep->flags, F_REVENGE, B_TRUE, NA, NA, NULL); f->known = B_TRUE; + + br = findbrand(BR_REVENGE); + copyflags(wep->flags, br->flags, FROMBRAND); + addflag(wep->flags, F_HASBRAND, BR_REVENGE, NA, NA, NULL); } else { switch (rnd(1,7)) { case 1: diff --git a/io.c b/io.c index 81bb44e..a1df936 100644 --- a/io.c +++ b/io.c @@ -41,7 +41,7 @@ extern int nbuildingusage; int hascolour = B_TRUE; -int noredraw = B_FALSE; +int noredraw = 0; int escok = B_TRUE; @@ -4166,7 +4166,7 @@ int updateviewfor(cell_t *cell) { void drawscreen(void) { int didstatus = B_FALSE; int didredraw = B_FALSE; - if (gamemode < GM_GAMESTARTED) { + if ((gamemode < GM_GAMESTARTED) || noredraw) { return; } @@ -7475,9 +7475,11 @@ char *makedesc_ob(object_t *o, char *retbuf) { strncat(retbuf, buf, HUGEBUFLEN); } if (f->val[2] != NA) { - sprintf(buf, " (bonus at %d)^n.\n", f->val[2]); + char addon[BUFLEN]; + sprintf(addon, " (bonus at %d)^n.\n", f->val[2]); + strcat(buf,addon); } else { - sprintf(buf, "\n"); + strcat(buf, "\n"); } strncat(retbuf, buf, HUGEBUFLEN); @@ -11832,14 +11834,19 @@ void redraw(void) { } void redrawpause(void) { - noredraw = B_TRUE; + noredraw++; } void redrawresume(void) { + /* noredraw = B_FALSE; if (needredraw) { drawlevelfor(player); } + */ + if (noredraw > 0) { + noredraw--; + } } void restoregamewindows(void) { @@ -12221,6 +12228,8 @@ void showlfstats(lifeform_t *lf, int showall) { y = 0; ch = '\0'; if (mode == '@') { + object_t *tempob = NULL; + int amt; int temp,ctemp; getcelltemp(lf->cell, &ctemp); temp = getlftemp(lf); @@ -13019,13 +13028,18 @@ void showlfstats(lifeform_t *lf, int showall) { if (f && (f->known)) { wrapprint(mainwin, &y, &x, 0, "%s %s noncorporeal and can walk through walls. ", you(lf), is(lf)); } - f = lfhasflag(lf, F_PRODUCESLIGHT); - if (f && (f->known)) { - int amt; - getmaxflags(lf->flags, F_PRODUCESLIGHT, &amt, NULL, NULL); - wrapprint(mainwin, &y, &x, 0, "%s produce%s light (minimum vision range: %d). ", you(lf), - isplayer(lf) ? "" : "s", - amt); + amt = lfproduceslight(lf,&tempob); + if (amt > 0) { + char obname[BUFLEN]; + char youstr[BUFLEN]; + if (tempob) { + getobname(tempob, obname, 1); + sprintf(youstr, "%s %s",your(lf),noprefix(obname)); + } else { + sprintf(youstr, "%s",you(lf)); + } + wrapprint(mainwin, &y, &x, 0, "%s produce%s light (minimum vision range: %d). %s", youstr, + isplayer(lf) ? "" : "s", amt); } f = lfhasknownflag(lf, F_SLOWMETAB); if (f && (f->known)) { diff --git a/lf.c b/lf.c index 3f07ffd..5c57090 100644 --- a/lf.c +++ b/lf.c @@ -26,7 +26,6 @@ extern double precos[]; extern FILE *logfile; -extern int noredraw; extern int enteringmap; extern int playerorigalignment; @@ -365,17 +364,12 @@ long calcscore(lifeform_t *lf) { int calcxp(lifeform_t *lf) { float multiplier = 1; float xpval = 0; - float offense = 0; - float defence = 0; - float spells = 0; flag_t *f; - float avgdam = 0; int db = B_FALSE; - int maxhdroll; int i; float xpconstant = 1; - flag_t *retflag[MAXCANDIDATES]; - int nretflags; + enum RARITY rr; + int mylev; if (lfhasflag(lf, F_DEBUG)) { db = B_TRUE; @@ -394,6 +388,18 @@ int calcxp(lifeform_t *lf) { return f->val[0] * multiplier; } + mylev = gettr(lf); + xpval = mylev * 3; + if (db) dblog("calcxp: base xpval from threatlev %f is %d\n",gettr(lf), (int)xpval); + + // rarity? + getracerarity(H_ALL, lf->race->id, &rr); + + for (i = 0;i < rr; i++) { + xpval += (mylev * 3); + } + + /* // attack // - get average attack damage @@ -538,6 +544,7 @@ int calcxp(lifeform_t *lf) { xpval += f->val[0]; if (db) dblog("calcxp: F_XPMOD is %d",f->val[0]); } + */ if (multiplier > 1) { xpval *= multiplier; @@ -558,17 +565,16 @@ int calcxprace(enum RACE rid) { int xpval; map_t m; lifeform_t *lf; - // set up fake map - m.lf = NULL; - m.lastlf = NULL; - // make a fake cell - setcelltype(&c, CT_CORRIDOR); - c.lf = NULL; - c.map = &m; + + createfakes(&m, &c); + // make a fake lf + redrawpause(); lf = addlf(&c, rid, 1); xpval = calcxp(lf); killlf(lf); + redrawresume(); + killfakes(&m, &c); return xpval; } @@ -4323,10 +4329,12 @@ void dumpmonsters(enum HABITAT hab) { getracerarity(hab, r->id, &rr); if ((thishd == wanthd) && (rr == i)) { int max; + int thisxp; f = hasflag(r->flags, F_HITDICE); max = flagtomaxhp(f); - dblog("\t%s (%d hp)",r->name, max); - fprintf(out, "\t\t%s (%d hp)
\n",r->name, max); + thisxp = calcxprace(r->id); + dblog("\t%s (%d hp, %d xp)",r->name, max, thisxp); + fprintf(out, "\t\t%s (%d hp, %d xp)
\n",r->name, max, thisxp); thiscount++; } } @@ -4685,8 +4693,10 @@ int digcell(lifeform_t *lf, cell_t *c, object_t *o, int dismantle) { int digdown(lifeform_t *lf, object_t *o) { char lfname[BUFLEN]; + enum OBTYPE digoid = OT_NONE; getlfname(lf, lfname); + if (o) { if (lfhasflag(lf, F_LEVITATING)) { if (isplayer(lf)) { @@ -4694,6 +4704,17 @@ int digdown(lifeform_t *lf, object_t *o) { } return B_TRUE; } + digoid = o->type->id; + } + + // is cell diggable at all? + if (!isdiggable(lf->cell, digoid)) { + if (isplayer(lf)) { + msg("The floor here is too hard to dig through."); + } else if (cansee(player, lf)) { + msg("%s tries to dig a hole in the floor, but fails.", lfname); + } + return B_TRUE; } // TODO: check if the floor is solid? @@ -5157,8 +5178,11 @@ int eat(lifeform_t *lf, object_t *o) { if (!isimmuneto(lf->flags, DT_POISON, B_FALSE)) { if (isrotting(o)) { char dambuf[BUFLEN]; + char plainobname[BUFLEN]; enum POISONTYPE ptid; int ppower = 1; + + getobnametruebase(o, plainobname, 1); // lose hp if (isplayer(lf)) { @@ -5166,9 +5190,9 @@ int eat(lifeform_t *lf, object_t *o) { } // food poisoning for 20 turns if (drinking) { - snprintf(dambuf, BUFLEN, "%s",obname); + snprintf(dambuf, BUFLEN, "%s",plainobname); } else { - snprintf(dambuf, BUFLEN, "a bad %s",noprefix(obname)); + snprintf(dambuf, BUFLEN, "a bad %s",noprefix(plainobname)); } if (onein(3)) { ptid = P_FOODBAD; @@ -10666,6 +10690,7 @@ int getracerarity(enum HABITAT hab, enum RACE rid, enum RARITY *rr) { f = hasflagval(r->flags, F_RARITY, H_ALL, NA, NA, NULL); } } else { + // just take the FIRST rarity flag. f = hasflag(r->flags, F_RARITY); } /*if (!f) { @@ -11488,9 +11513,9 @@ void getwantdistance(lifeform_t *lf, lifeform_t *victim, int *min, int *max, int } } } else { - // default - stay with 1-3 cells + // default - stay with 1-2 cells *min = 1; - *max = 3; + *max = 2; f = lfhasflag(lf, F_FOLLOWRANGE); if (f) { *min = f->val[0]; @@ -14013,7 +14038,7 @@ int lockpick(lifeform_t *lf, cell_t *targcell, object_t *target, object_t *devic } removeob(device, 1); } else if (faileffect == B_BLUNTONFAIL) { - if (!makeduller(device, 1)) { + if (!makedullermaybe(device, 1)) { if (isplayer(lf) || cansee(player, lf)) { msg("%s fail%s to unlock %s.",lfname, isplayer(lf) ? "" : "s", obname); } @@ -15210,6 +15235,8 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) { int i; //int db = B_FALSE; + redrawpause(); + assert(cell); if (cell->type != (celltype_t *) DUMMYCELLTYPE) { assert(!cell->type->solid); @@ -15353,6 +15380,8 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) { // set home room. sethomeroom(a); + redrawresume(); + return a; } @@ -15980,6 +16009,9 @@ lifeform_t *makezombie(object_t *o, int power, char *description, lifeform_t *ma killflagsofid(lf->flags, F_DTRESIST); addraceclassflags(lf->flags, RC_UNDEAD, R_NONE); + // less night/day penalty/bonus for raised undead. + killflagsofid(lf->flags, F_DAYBOOST); + killflagsofid(lf->flags, F_NIGHTBOOST); if (hasflag(o->flags, F_HEADLESS)) { // remove the head @@ -18813,6 +18845,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume, int lbonus; int myvol; int nwalls = 0; + int hearable = B_FALSE; flag_t *sleepflag; if (l == noisemaker) continue; @@ -18849,6 +18882,10 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume, */ myvol = volume; + hearable = canhear(l,c,myvol,&nwalls); + // adjust volume for number of walls + myvol -= nwalls; + // listen bonus is based on sound volume lbonus = (myvol*5); if (sleepflag) { @@ -18856,9 +18893,10 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume, limit(&lbonus, 0, NA); } + // skillcheck to hear this if ( (isplayer(l) && haslos(l, c)) || // only player can "hear by seeing" - (canhear(l, c, myvol, &nwalls) && (alwayshear || skillcheck(l, SC_LISTEN, difficulty, lbonus)) ) ) { + (hearable && (alwayshear || skillcheck(l, SC_LISTEN, difficulty, lbonus)) ) ) { flag_t *f; // announce? if (isplayer(l) && !lfhasflag(l, F_ASLEEP)) { @@ -26240,6 +26278,8 @@ int validateraces(void) { flag_t *retflag[MAXCANDIDATES]; int nretflags; + redrawpause(); + // generate xp list genxplist(); @@ -26448,7 +26488,7 @@ int validateraces(void) { killfakes(&fakemap, &fakecell); - noredraw = B_FALSE; + redrawresume(); return goterror; } diff --git a/map.c b/map.c index 67b67f3..890fddc 100644 --- a/map.c +++ b/map.c @@ -4336,6 +4336,7 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_ } void createfakes(map_t *map, cell_t *cell) { + redrawpause(); map->region = NULL; map->lf = NULL; map->lastlf = NULL; @@ -4346,6 +4347,7 @@ void createfakes(map_t *map, cell_t *cell) { cell->obpile = addobpile(NULL, NULL, NULL); cell->room = NULL; setcelltype(cell, CT_FAKE); + redrawresume(); } void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob, int nclearings) { @@ -4618,7 +4620,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex // don't redraw screen during level change calculations - noredraw = B_TRUE; + redrawpause(); //if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging @@ -5336,7 +5338,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex // put a last fixreachability call in... fix_reachability(map); - noredraw = B_FALSE; + redrawresume(); map->beingcreated = B_FALSE; if (db) { @@ -8984,7 +8986,7 @@ int isdiggable(cell_t *c, enum OBTYPE withwhat) { case CT_WALLDIRT: case CT_WALL: case CT_WALLWOOD: - case CT_WALLGLASS: + //case CT_WALLGLASS: return B_TRUE; default: break; diff --git a/move.c b/move.c index bbeec61..41fcf84 100644 --- a/move.c +++ b/move.c @@ -27,8 +27,6 @@ extern enum GAMEMODE gamemode; extern enum ERROR reason; extern void *rdata; -extern int noredraw; - extern long curtime; extern condset_t ccwalkable; @@ -1278,7 +1276,7 @@ int movelf(lifeform_t *lf, cell_t *newcell, int onpurpose) { o = hasobid(newcell->obpile, barrierid); if (o) killob(o); - if (isplayer(lf)) noredraw = B_FALSE; + if (isplayer(lf)) redrawresume(); } // remember current cell + room id diff --git a/nexus.c b/nexus.c index 798482c..1fac900 100644 --- a/nexus.c +++ b/nexus.c @@ -125,8 +125,6 @@ int prevhour = -1; // previous Hour extern int statdirty; -extern int noredraw; - int needredraw = B_TRUE; int numdraws = 0; @@ -1442,29 +1440,51 @@ void gethitdicestats(lifeform_t *lf, int *ndice,int *nsides,int *plus) { } } -void gettrrange(int depth, int *min, int *max, int range, int oodok) { - int mid; - // adjust depth for out-of-depth monsters - if (oodok && (onein(6))) { - depth++; +// TODO: "range" is currently unused. +void gettrrange(int depth, int *min, int *max, int range, int oodok) { + int upchance = 3; + int downchance = 1; + + // initial threat rating is the same as dungeon depth. + // ie. dungeon level 1 has TR 1 monsters + // ie. dungeon level 6 has TR 6 monsters + // + // then add an ever-decreasing chance of this difficulty + // incrementing for each level. + + *min = depth; + *max = depth; + + // adjust max depth for out-of-depth monsters + if (oodok && (onein(upchance))) { + (*max)++; + upchance++; // repeated chances of incing level - while (onein(6)) { - depth++; + while ((upchance < 10) && (*max < maxmonhitdice) && onein(upchance)) { + (*max)++; + upchance++; + } + } + + // adjust min depth for chance of easier monsters + if (onein(downchance)) { + (*min)--; + downchance++; + while ((downchance < 10) && (*min > 1) && onein(downchance)) { + (*min)--; + downchance += 2; } } - //mid = (depth/2); - mid = (depth); + //*min = mid - range - 10; + //*min = mid - (range*2); + //limit(min, 0, 8); + //*max = mid + range; - *min = mid - range - 10; - //limit(min, 0, maxmonhitdice); - limit(min, 0, 8); - - *max = mid + range; + // these shouldn't really be needed now + limit(min, 1, NA); limit(max, *min, maxmonhitdice); - - } int getoption(enum OPTION id) { @@ -1516,32 +1536,44 @@ char getpctletter(float num, float max) { } void getrarityrange(int depth, int *min, int *max, int range, int oodok) { - int mid; - int num; + int upchance = 2; + int downchance = 3; - // adjust depth for out-of-depth things - if (oodok && (onein(6))) { - // repeated 1/3 chances of incing level - num = rnd(1,6) - 4; - while (num > 0) { - depth += num; - num = rnd(1,6) - 4; + *min = depth; + *max = depth; + + // adjust max depth for better objects + if (oodok && (onein(upchance))) { + (*max)++; + upchance++; + // repeated chances of incing level + while ((upchance < 10) && (*max < MAXDEPTH) && onein(upchance)) { + (*max)++; + upchance++; } } - mid = 100 - (depth * 3); - *min = mid - range; if (*min < 0) *min = 0; - // *max = mid + range; if (*max > 100) *max = 100; - *max = 100; + // adjust min depth for worse objects + if (onein(downchance)) { + (*min)--; + downchance++; + while ((downchance < 10) && (*min > 1) && onein(downchance)) { + (*min)--; + downchance++; + } + } + limit(min,1,NA); + limit(max,*min,MAXDEPTH); //if (*min > 85) *min = 85; - if (*max < 25) *max = 25; + //if (*max < 25) *max = 25; } int init(void) { int i; // random numbers - srand(time(NULL)); + //srand(time(NULL)); + sranddev(); // preset conditions initcondv(&ccwalkable, CC_WALKABLE, B_TRUE, NA, @@ -2248,7 +2280,7 @@ void timeeffectsworld(map_t *map, int updategametime) { } // end for (y... // now finish off water spread - noredraw = B_TRUE; + redrawpause(); getflags(map->flags, retflag, &nretflags, F_NEWWATERDEPTH, F_NONE); assert(nretflags < MAXCANDIDATES); // oooooooooooooo @@ -2267,7 +2299,7 @@ void timeeffectsworld(map_t *map, int updategametime) { } } killflagsofid(map->flags, F_NEWWATERDEPTH); - noredraw = B_FALSE; + redrawresume(); // now handle effects on lifeforms and/or their objects diff --git a/objects.c b/objects.c index 7531602..0493b70 100644 --- a/objects.c +++ b/objects.c @@ -6296,16 +6296,16 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan } } - // eaten? - f = hasflag(o->flags, F_EDIBLE); - if (f && (f->val[2] != NA)) { - strcat(localbuf, "partially eaten "); - } // condition // include mods // ie. a blessed ->damaged<- flaming +5 silver sword of pyromania if (wantcondition) { + // eaten? + f = hasflag(o->flags, F_EDIBLE); + if (f && (f->val[2] != NA)) { + strcat(localbuf, "partially eaten "); + } if (!hasflag(o->flags, F_NOOBDAMTEXT)) { getobconditionname(o, buf2); if (strlen(buf2) > 0) { @@ -8844,6 +8844,14 @@ int makeduller(object_t *o, int howmuch) { } +int makedullermaybe(object_t *o, int howmuch) { + if (onein(3)) { + return makeduller(o, howmuch); + } + return B_FALSE; +} + + void makehot(object_t *o, int howmuch, int howlong) { flag_t *f; int seen = B_FALSE; @@ -12416,7 +12424,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE msg("%s writhes in agony!", lfname); } dam = rnd(5,10); - losehp(lf, dam, DT_ACID, NULL, "drinking acid"); + losehp_real(lf, dam, DT_ACID, NULL, "drinking acid", B_FALSE, o, B_FALSE, NULL, B_FALSE, BP_NONE, B_FALSE); break; case OT_POT_ACROBATICS: if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 150, 0)) { diff --git a/objects.h b/objects.h index 3bacda4..bec7352 100644 --- a/objects.h +++ b/objects.h @@ -251,6 +251,7 @@ int knockbackob(object_t *o, int dir, int howfar, int power, lifeform_t *pusher) lifeform_t *makeanimated(lifeform_t *lf, object_t *o, int level); void makecool(object_t *o, int howmuch, int howlong); int makeduller(object_t *o, int howmuch); +int makedullermaybe(object_t *o, int howmuch); void makehot(object_t *o, int howmuch, int howlong); void makeknown(enum OBTYPE otid); void makeknownobclass(enum OBCLASS ocid, enum RARITY rrlev); diff --git a/save.c b/save.c index 16a363f..7bb1e4c 100644 --- a/save.c +++ b/save.c @@ -56,13 +56,19 @@ int loadall(void) { int loadflagpile(FILE *f, flagpile_t *fp) { flag_t tempflag; flag_t *fl; + char line[BUFLEN]; char buf[BUFLEN]; int rv; - int skid; + int skid = -9999; int db = B_FALSE; - rv = fscanf(f, "%d,%d,%d,%d,%d,%d,%d,%ld,%d\n", + fscanf(f, "flags:\n"); + + fgets(line, BUFLEN, f); + rv = sscanf(line, "%d,%d,%d,%d,%d,%d,%d,%ld,%d\n", &tempflag.id, &tempflag.nvals, &tempflag.val[0], &tempflag.val[1], &tempflag.val[2],&tempflag.lifetime, &tempflag.known,&tempflag.obfrom,&skid); + assert(rv == 9); + assert(skid != -9999); while (tempflag.id != -1) { dblog("got flag id=%d\n",tempflag.id); @@ -83,8 +89,9 @@ int loadflagpile(FILE *f, flagpile_t *fp) { } // load next one - rv = fscanf(f, "%d,%d,%d,%d,%d,%d,%d,%ld\n", - &tempflag.id, &tempflag.nvals, &tempflag.val[0], &tempflag.val[1], &tempflag.val[2],&tempflag.lifetime, &tempflag.known,&tempflag.obfrom); + fgets(line, BUFLEN, f); + rv = sscanf(line, "%d,%d,%d,%d,%d,%d,%d,%ld,%d\n", + &tempflag.id, &tempflag.nvals, &tempflag.val[0], &tempflag.val[1], &tempflag.val[2],&tempflag.lifetime, &tempflag.known,&tempflag.obfrom,&skid); //dblog("fscanf returned %d\n",rv); } return B_FALSE; @@ -158,7 +165,7 @@ lifeform_t *loadlf(FILE *f, cell_t *where) { if (db) dblog("--> Loading lifeform...\n"); - fscanf(f, "startlf\n"); + //fscanf(f, "startlf\n"); fscanf(f, "lfid: %d\n",&lfid); fscanf(f, "race: %d\n",&lfraceid); fscanf(f, "map: %d\n",&mapid); @@ -587,8 +594,6 @@ int loadob(FILE *f, obpile_t *op, long *id) { killflag(o->flags->first); } - fscanf(f, "flags:\n"); - dblog("About to start loading object flags..."); loadflagpile(f, o->flags); @@ -736,6 +741,7 @@ int loadsavegame(void) { exit(1); } // load player + fscanf(f, "startlf\n"); if (!loadlf(f, NULL)) { printf("Error loading player from save file."); exit(1); @@ -919,8 +925,11 @@ int saveflagpile(FILE *f, flagpile_t *fp) { flag_t *fl; fprintf(f, "flags:\n"); for (fl = fp->first ; fl ; fl = fl->next) { + + assert(!fl->skillfrom || findskill(fl->skillfrom->id)); + fprintf(f, "%d,%d,%d,%d,%d,%d,%d,%ld,%d\n", - fl->id, fl->nvals, fl->val[0], fl->val[1], fl->val[2],fl->lifetime,fl->known,fl->obfrom, fl->skillfrom->id); + fl->id, fl->nvals, fl->val[0], fl->val[1], fl->val[2],fl->lifetime,fl->known,fl->obfrom, fl->skillfrom ? fl->skillfrom->id : SK_NONE); if (!fl->text || !strcmp(fl->text, "")) { fprintf(f, "%s\n","^^^"); } else { diff --git a/shops.c b/shops.c index 0485c6a..7fe0938 100644 --- a/shops.c +++ b/shops.c @@ -179,7 +179,8 @@ void shop(lifeform_t *lf, object_t *vm) { } // closed? - if (shopisclosed(vm)) { + f = shopisclosed(vm); + if (f) { sayphrase(NULL, f->val[2], SV_TALK, hoursto12(f->val[0]), NULL, player); return; } @@ -800,17 +801,18 @@ enum SHOPRETURN shopid(lifeform_t *lf, object_t *vm, int starty, char *toptext, return SR_CONTINUE; } -int shopisclosed(object_t *shop) { +// returns F_OPENHOURS flag if the shop is closed. +flag_t *shopisclosed(object_t *shop) { flag_t *f; f = hasflag(shop->flags, F_OPENHOURS); if (f) { int h = -1,m = -1,s = -1; splittime(&h, &m, &s); if (!timeisbetween(h, f->val[0], f->val[1])) { - return B_TRUE; + return f; } } - return B_FALSE; + return NULL; } enum SHOPRETURN shopmiracle(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *ndonated) { diff --git a/shops.h b/shops.h index 4f76195..3d4a9e3 100644 --- a/shops.h +++ b/shops.h @@ -12,7 +12,7 @@ enum SHOPRETURN shopbless(lifeform_t *lf, object_t *vm, int starty, char *toptex enum SHOPRETURN shopdonate(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased); enum SHOPRETURN shopdetectcurse(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased); enum SHOPRETURN shopid(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *nid); -int shopisclosed(object_t *shop); +flag_t *shopisclosed(object_t *shop); enum SHOPRETURN shopmiracle(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased); enum SHOPRETURN shoppurchase(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased); enum SHOPRETURN shoprepair(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased); diff --git a/spell.c b/spell.c index 82d3df8..f5daed5 100644 --- a/spell.c +++ b/spell.c @@ -27,7 +27,6 @@ extern region_t *firstregion; extern knowledge_t *knowledge; extern int needredraw; -extern int noredraw; extern prompt_t prompt; @@ -473,7 +472,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } - noredraw = B_TRUE; + redrawpause(); // move any lfs at the other end out of the way. if (c->lf) { @@ -788,7 +787,8 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef // we now need born to be true so that precalclos() works. user->born = B_TRUE; - noredraw = B_FALSE; // allow redraws + // allow redraws + redrawresume(); setlosdirty(user); // this will redraw the screen askcoords("Peek (ESC when done)->", "Peek (ESC when done)->", TT_NONE, user, UNLIMITED, LOF_DONTNEED, B_FALSE); user->born = B_FALSE; @@ -809,7 +809,9 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef // move lf back movelf(movedlf, c, B_FALSE); } - noredraw = B_FALSE; + // resume redrawing capability. + // might have already been done if we used the 'p'eek commaned (see above). + redrawresume(); if (ch == 'p') { // if we peeked, then we have to redraw now. @@ -3380,6 +3382,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef debug(where->lf); } } else if (abilid == OT_A_DUMPMON) { + msg("Dumping monsters..."); dumpmonsters(H_DUNGEON); msg("Monster list dumped to monsters.html."); } else if (abilid == OT_A_PATHFIND) { @@ -6413,7 +6416,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (haslos(player, c)) seenthiscell = B_TRUE; if (c->type->solid) { - if ((c->type->material->id == MT_STONE) || (c->type->material->id == MT_FLESH)) { + if (isdiggable(c, OT_S_DIG)) { int d2; if (seenthiscell) { msg("%s %s collapses!", needan(c->type->name) ? "An" : "A",