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 2547cef..11d1b50 100644
Binary files a/data/hiscores.db and b/data/hiscores.db differ
diff --git a/god.c b/god.c
index 7076465..104349c 100644
--- a/god.c
+++ b/god.c
@@ -1573,12 +1573,17 @@ int godgiftmaybe(enum RACE rid, int fromtemple, int announce) {
wep = getweapon(player);
if (wep && !hasflag(wep->flags, 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",