diff --git a/ai.c b/ai.c index 1b303f4..c4f2b77 100644 --- a/ai.c +++ b/ai.c @@ -88,9 +88,9 @@ int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) { } // become hostile? - if (!hasflag(lf->flags, F_HOSTILE)) { + if (isplayer(victim) && !hasflag(lf->flags, F_HOSTILE) ) { addflag(lf->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); - innocentattack = 1; + //innocentattack = 1; } // change allegience ? @@ -104,7 +104,7 @@ int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) { // no longer a pet f = lfhasflagval(lf, F_PETOF, victim->id, NA, NA, NULL); if (f) { - innocentattack = 3; + if (isplayer(victim)) innocentattack = 3; killflag(f); } diff --git a/attack.c b/attack.c index e721888..9e98e0b 100644 --- a/attack.c +++ b/attack.c @@ -111,10 +111,26 @@ void applyarmourdamreduction(lifeform_t *lf, object_t *wep, int reduceamt, int * // figure out reduced damage value if (dam) { + int ar; + newdam = *dam; + ar = getarmourrating(lf, NULL, NULL, NULL); + // if you did at least one damage... if ((*dam >= 1) && (reduceamt >= 0)) { + int lowerlimit = 0,divideby; + // reduce it. newdam -= reduceamt; - limit(&newdam, 1, NA); // don't reduce to <1 damage + + // you will always take at least 1 hp of damage for every (ar/2) damage. + // ie. if you took ar/2 damage, you take at least 1. + // ie. if you took ar damage, you take at least 2. + // ie. if you took ar*2 damage, you take at least 3. + // stop at 3. + divideby = ar/2; + if (divideby <= 0) divideby = 1; + lowerlimit = (*dam / divideby); + limit(&lowerlimit, 0, 3); + limit(&newdam, lowerlimit, NA); // don't reduce too far. } if (db) { @@ -811,7 +827,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) strcpy(attackverb, getattackverb(lf, wep, damtype[i],dam[i],victim->maxhp)); if ((dam[i] == 0) && (damtype[i] != DT_TOUCH)) { nodam = B_TRUE; - strcpy(nodamstr, " but does no damage"); + strcpy(nodamstr, " ineffectually"); } else { strcpy(nodamstr, ""); } diff --git a/data/hiscores.db b/data/hiscores.db index aede53a..9915837 100644 Binary files a/data/hiscores.db and b/data/hiscores.db differ diff --git a/defs.h b/defs.h index 9d08c47..a0f9d6c 100644 --- a/defs.h +++ b/defs.h @@ -2352,6 +2352,10 @@ enum PIETYLEV { #define B_FALSE (0) #define B_TRUE (-1) +#define B_VIS (1) +#define B_UNKNOWN (0) +#define B_NOVIS (-1) + #define B_KEEPLOF (-1) #define B_MALE (0) @@ -2807,6 +2811,9 @@ typedef struct lifeform_s { int nlos; cell_t **los; + int *viscell; + int visw; + int visrange; // set to TRUE after lf has being created int born; diff --git a/flag.c b/flag.c index b6e2d67..05ac29b 100644 --- a/flag.c +++ b/flag.c @@ -3,6 +3,7 @@ #include #include "defs.h" #include "flag.h" +#include "god.h" #include "io.h" #include "lf.h" #include "map.h" @@ -17,6 +18,9 @@ extern enum GAMEMODE gamemode; extern int needredraw; extern int statdirty; +extern lifeform_t *godlf[]; +extern int ngodlfs; + extern lifeform_t *player; int flagdb = B_FALSE; @@ -684,6 +688,11 @@ void killflag(flag_t *f) { map_t *redolight = NULL; int redostat = B_FALSE; int redoscreen = B_FALSE; + int i,dopleasegod[MAXGODS]; + + for (i = 0; i < ngodlfs; i++) { + dopleasegod[i] = 0; + } lf = f->pile->owner; @@ -705,6 +714,16 @@ void killflag(flag_t *f) { if (lf && (isplayer(lf) || cansee(player, lf))) { redolight = lf->cell->map; } + } else if (f->id == F_FLEEFROM) { + if (lf && lf->cell) { + lifeform_t *fleefrom; + fleefrom = findlf(lf->cell->map, f->val[0]); + // ie. this lf was fleeing from the player, and + // got away. + if (isplayer(fleefrom) && !cansee(lf, fleefrom)) { + dopleasegod[R_GODMERCY] += 5; + } + } } } @@ -792,6 +811,11 @@ void killflag(flag_t *f) { updatefpindex(f->pile); if (gamemode == GM_GAMESTARTED) { + for (i = 0; i < ngodlfs; i++) { + if (dopleasegod[i]) { + pleasegodmaybe(godlf[i]->race->id, dopleasegod[i]); + } + } if (redolight) { calclight(redolight); precalclos(player); diff --git a/god.c b/god.c index 55a750d..1b63807 100644 --- a/god.c +++ b/god.c @@ -97,11 +97,20 @@ void angergod(enum RACE rid, int amt) { // then... if (piety > -100) { int i,n; + lifeform_t *l; // minor bad stuff switch (rid) { case R_GODDEATH: castspell(god, OT_S_PAIN, player, NULL, player->cell); castspell(god, OT_S_DRAINLIFE, player, NULL, player->cell); + // all undead in sight become hostile + for (l = player->cell->map->lf ; l ; l = l->next) { + if (!isplayer(l) && isundead(l) && cansee(l, player)) { + if (getallegiance(l) != AL_HOSTILE) { + aiattack(l, player, PERMENANT); + } + } + } break; case R_GODTHIEVES: // take a random object @@ -139,12 +148,21 @@ void angergod(enum RACE rid, int amt) { } } else if (piety > -200) { object_t *o; + lifeform_t *l; int n,i; // major bad stuff switch (god->race->id) { case R_GODDEATH: castspell(god, OT_S_PAIN, player, NULL, player->cell); castspell(god, OT_S_DRAINLIFE, player, NULL, player->cell); + // all undead in sight become hostile + for (l = player->cell->map->lf ; l ; l = l->next) { + if (!isplayer(l) && isundead(l) && cansee(l, player)) { + if (getallegiance(l) != AL_HOSTILE) { + aiattack(l, player, PERMENANT); + } + } + } switch (rnd(1,2)) { case 1: msg("\"This will teach you some humility, mortal!\""); diff --git a/io.c b/io.c index 6ee1558..6bfc816 100644 --- a/io.c +++ b/io.c @@ -6037,6 +6037,7 @@ void drawlevelfor(lifeform_t *lf) { if (db) dblog("ending DRAWLEVEL"); sprintf(buf, "end. ndrawn was %d",ndrawn); + if (db) dblog("%s",buf); //dbtimeend(buf); // move cursor to the player's position and blit if (ndrawn) { diff --git a/lf.c b/lf.c index fca4ad7..f62b457 100644 --- a/lf.c +++ b/lf.c @@ -195,32 +195,40 @@ void bleed(lifeform_t *lf) { } } -void breakallgrabs(lifeform_t *lf) { +void breakgrabs(lifeform_t *lf, int fromme, int tome) { flag_t *f; lifeform_t *alf; - f = lfhasflag(lf, F_GRABBING); - if (f) { - lifeform_t *grabee; - grabee = findlf(NULL, f->val[0]); - assert(grabee); - killflagsofid(grabee->flags, F_GRABBEDBY); - killflagsofid(lf->flags, F_GRABBING); - } - f = lfhasflag(lf, F_GRABBEDBY); - if (f) { - lifeform_t *graber; - graber = findlf(NULL, f->val[0]); - assert(graber); - killflagsofid(graber->flags, F_GRABBING); - killflagsofid(lf->flags, F_GRABBEDBY); - } - - for (alf = lf->cell->map->lf ; alf ; alf = alf->next) { - f = lfhasflagval(alf, F_ATTACHEDTO, lf->id, NA, NA, NULL); + if (fromme) { + f = lfhasflag(lf, F_GRABBING); + if (f) { + lifeform_t *grabee; + grabee = findlf(NULL, f->val[0]); + assert(grabee); + killflagsofid(grabee->flags, F_GRABBEDBY); + killflagsofid(lf->flags, F_GRABBING); + } + f = lfhasflag(lf, F_ATTACHEDTO); if (f) { killflag(f); } } + if (tome) { + f = lfhasflag(lf, F_GRABBEDBY); + if (f) { + lifeform_t *graber; + graber = findlf(NULL, f->val[0]); + assert(graber); + killflagsofid(graber->flags, F_GRABBING); + killflagsofid(lf->flags, F_GRABBEDBY); + } + + for (alf = lf->cell->map->lf ; alf ; alf = alf->next) { + f = lfhasflagval(alf, F_ATTACHEDTO, lf->id, NA, NA, NULL); + if (f) { + killflag(f); + } + } + } } long calcscore(lifeform_t *lf) { @@ -3281,6 +3289,13 @@ int flee(lifeform_t *lf) { flag_t *f; lifeform_t *fleefrom = NULL; int i; + int db = B_FALSE; + char lfname[BUFLEN]; + + if (lfhasflag(lf, F_DEBUG)) db = B_TRUE; + + real_getlfname(lf, lfname, B_FALSE); + // mindless? if (getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) == IQ_MINDLESS) { @@ -3304,16 +3319,16 @@ int flee(lifeform_t *lf) { // if we can't see the person we're running from, and it's not enforced for // a certain time period (ie. f->lifetime == PERMENANT), we can now stop fleeing. if (f->lifetime == PERMENANT) { + // player let something flee? + if (isplayer(thisone)) { + pleasegodmaybe(R_GODMERCY, 5); + angergodmaybe(R_GODDEATH, 25); + } killflag(f); } else { // if the flag is temporary, keep fleeing and wait for it to time out normally fleefrom = thisone; } - // player let something flee? - if (isplayer(thisone)) { - pleasegodmaybe(R_GODMERCY, 5); - angergodmaybe(R_GODDEATH, 25); - } } } } @@ -3323,7 +3338,9 @@ int flee(lifeform_t *lf) { if (fleefrom) { object_t *stairs; - breakallgrabs(lf); + if (db) dblog("%s - fleeing from %s", lfname, fleefrom->race->name); + + breakgrabs(lf, B_TRUE, B_FALSE); // stop grabbing anyone // ways of fleeing other than movement? if (!isplayer(lf)) { @@ -3339,14 +3356,23 @@ int flee(lifeform_t *lf) { aigetspelltarget(lf, findot(spell), fleefrom, &targlf, &targcell, &targob, F_AICASTTOFLEE); if (getschool(spell) == SS_ABILITY) { - return useability(lf, spell, targlf, targcell); + if (db) dblog("%s - using ability %s to flee", sp->name); + if (!useability(lf, spell, targlf, targcell)) { + if (db) dblog("%s - success.", lfname); + return B_TRUE; + } } else { - return castspell(lf, spell, targlf, targob, targcell); + if (db) dblog("%s - casting %s to flee", sp->name); + if (!castspell(lf, spell, targlf, targob, targcell)) { + if (db) dblog("%s - success.", lfname); + return B_TRUE; + } } } // if AI, use helpful fleeing items if (!useitemwithflag(lf, F_AIFLEEITEM)) { - return B_FALSE; + if (db) dblog("%s - used an item to flee", lfname); + return B_TRUE; } } @@ -3362,13 +3388,16 @@ int flee(lifeform_t *lf) { stairs = hasobwithflag(lf->cell->obpile, F_CLIMBABLE); if (stairs) { if (!usestairs(lf, stairs, B_TRUE)) { + if (db) dblog("%s - fleeing via %s", stairs->type->name); return B_TRUE; } } // move away from them if (!moveawayfrom(lf, fleefrom->cell, DT_ORTH, B_FALSE)) { + if (db) dblog("%s - fleeing by moving away", lfname); return B_TRUE; } + if (db) dblog("%s - failed to flee!", lfname); } // if we get here, it means we didn't need to or couldn't flee @@ -3404,7 +3433,7 @@ void fleefrom(lifeform_t *lf, lifeform_t *enemy, int howlong, int onpurpose) { // already fleeing? f = hasflagval(lf->flags, F_FLEEFROM, enemy->id, NA, NA, NULL); if (f) { - // update time + // just update time if (f->lifetime != PERMENANT) { if (f->lifetime < howlong) { f->lifetime = howlong; @@ -3413,6 +3442,10 @@ void fleefrom(lifeform_t *lf, lifeform_t *enemy, int howlong, int onpurpose) { } else { addtempflag(lf->flags, F_FLEEFROM, enemy->id, NA, NA, NULL, howlong); } + + // stop targetting anyone or going anywhere + killflagsofid(lf->flags, F_TARGETLF); + killflagsofid(lf->flags, F_TARGETCELL); } int freezelf(lifeform_t *freezee, lifeform_t *freezer, int howlong) { @@ -7434,6 +7467,231 @@ int haslof(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest) { return B_TRUE; } + +void idxtoxy(lifeform_t *lf, int idx, int *x, int *y) { + int xoffset,yoffset; + // get the offset form the lf's position. + xoffset = (idx % lf->visw) - lf->visrange; + yoffset = (idx / lf->visw) - lf->visrange; + // return the actual cell there + *x = lf->cell->x + xoffset; + *y = lf->cell->y + yoffset; +} + +// confirmed good! +int xytoidx(lifeform_t *lf, int x, int y) { + int idx; + int xd,yd; + + if (abs(x - lf->cell->x) > lf->visrange) return -1; + if (abs(y - lf->cell->y) > lf->visrange) return -1; + + xd = lf->cell->x - lf->visrange; + yd = lf->cell->y - lf->visrange; + + idx = (y - yd) * lf->visw + (x - xd); + return idx; +} + +void setviscell(lifeform_t *lf, cell_t *cell, int how) { + int idx; + int x,y; + cell_t *c; + idx = xytoidx(lf, cell->x, cell->y); + assert(idx >= 0); + assert(idx < (lf->visw * lf->visw)); + lf->viscell[idx] = how; + + + // checks + if (how == B_VIS) { + assert (abs(lf->cell->x - cell->x) <= 10); + assert (abs(lf->cell->y - cell->y) <= 10); + } + + + idxtoxy(lf, idx, &x, &y); + c = getcellat(lf->cell->map, x, y); + assert(c); + +} + +int getviscell(lifeform_t *lf, cell_t *cell) { + int idx; + idx = xytoidx(lf, cell->x, cell->y); + if ((idx < 0) || (idx >= (lf->visw * lf->visw)) ) { + return B_NOVIS; + } + + return lf->viscell[idx]; +} + +// find los, remembering cells on the way +void calclos(lifeform_t *viewer, cell_t *dest) { + int numpixels; + int i,n; + int x1,y1; + int maxvisrange; + int nightvisrange; + int xray = 0; + flag_t *f; + int x2,y2; + map_t *map; + object_t *o; + int currange; + cell_t *retcell[MAXRETCELLS]; + int allbad = B_FALSE; + + if (!viewer) return ; + if (!dest) return ; + if (!viewer->cell) return ; + if (viewer->cell->map != dest->map) return ; + + map = dest->map; + + x1 = viewer->cell->x; + y1 = viewer->cell->y; + x2 = dest->x; + y2 = dest->y; + + // find the path of cells + calcbresnham(map, x1, y1, x2, y2, retcell, &numpixels); + + // can't see if you're blind + if (isblind(viewer)) { + allbad = 1; + } + + maxvisrange = getvisrange(viewer); + nightvisrange = getnightvisrange(viewer); + + //origheight = getheight(x1,y1,z); + + if (allbad) { + // mark all as bad + for (i = 0; i < numpixels; i++ ){ + setviscell(viewer, retcell[i], B_VIS); + } + return; + } + + + f = hasflag(viewer->flags, F_XRAYVIS); + if (f) { + xray = f->val[0]; + } else { + xray = 0; + } + + //shopwall = B_FALSE; + currange = 0; + + for (i = 0; i < numpixels ; i++) { + cell_t *cell; + int cellopaque = B_FALSE; + int celldark = B_FALSE; + + cell = retcell[i]; + + //already can't see this one? + if (getviscell(viewer, cell) == B_NOVIS) { + break; + } + + if ((cell->x == x2) && (cell->y == y2)) { + // made it to the last cell + setviscell(viewer, cell, B_VIS); + return; + } + + if (i == 0) { + // you can always see your own cell + setviscell(viewer, cell, B_VIS); + continue; + } + + + currange++; + if (currange > maxvisrange) { + break; + } + + // check cell type + if (!cell->type->transparent) { + cellopaque = -1; // fullblock + } + + // now check lighting + if (!cellopaque) { + // outside the range of our light, and not lit + if (getcelldist(viewer->cell, cell) > nightvisrange) { + if (!islit(cell)) { + celldark = B_TRUE; + } + } else { + // inside our nightvis range and magically dark + if (cell->lit == L_PERMDARK) { + celldark = B_TRUE; + } + } + } + + // check for objects which block view + if (!cellopaque && !celldark) { + for (o = cell->obpile->first ; o ; o = o->next) { + f = hasflag(o->flags, F_BLOCKSVIEW); + if (f) { + if (!lfhasflagval(viewer, F_CANSEETHROUGHMAT, o->material->id, NA, NA, NULL)) { + if (f->val[0] == B_TRUE) { + cellopaque = -1; // fullblock + break; + } else { + cellopaque += f->val[0]; + } + } + } + } + } + + if (cellopaque) { + if (xray) { + xray--; + } else { + if (cellopaque == -1) { + // can see this one but not the rest. + setviscell(viewer, cell, B_VIS); + i++; + break; + } else { + currange += cellopaque; + if (currange > maxvisrange) { + // can see this one but not the rest. + setviscell(viewer, cell, B_VIS); + i++; + break; + } + } + } + } + + // xray vision decreases by one + if (xray) xray--; + + // this cell is visible (unless it's dark) + if (celldark) { + setviscell(viewer, cell, B_NOVIS); + } else { + setviscell(viewer, cell, B_VIS); + } + } + + + // rest of cells are not visible. + for (n = i; n < numpixels; n++) { + setviscell(viewer, retcell[n], B_NOVIS); + } +} + int haslos(lifeform_t *viewer, cell_t *dest) { int numpixels; int i; @@ -7463,6 +7721,7 @@ int haslos(lifeform_t *viewer, cell_t *dest) { // can we use pre-calced los? // + if ((viewer->cell->map->lf == viewer) && viewer->los) { for (i = 0;i < viewer->nlos; i++) { if (viewer->los[i] == dest) { @@ -7626,7 +7885,7 @@ void initjobs(void) { addflag(lastjob->flags, F_STARTSKILL, SK_SS_DIVINATION, PR_MASTER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SS_MENTAL, PR_MASTER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SS_SUMMONING, PR_MASTER, NA, NULL); - addflag(lastjob->flags, F_HASPET, NA, NA, NA, "young wolf"); + //addflag(lastjob->flags, F_HASPET, NA, NA, NA, "young wolf"); for (i = 1; i < MAXSKILLS; i++) { addflag(lastjob->flags, F_CANLEARN, i, NA, NA, NULL); } @@ -11378,7 +11637,10 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) { // for precalcing line of sight a->nlos = 0; - a->los = NULL; + //a->los = malloc(sizeof(cell_t *) * MAXVISRANGE); + a->los = malloc( sizeof(cell_t *) * ((MAXVISRANGE*2+1)*(MAXVISRANGE*2+1))); + //a->viscell = NULL; + a->viscell = malloc( sizeof(int) * ((MAXVISRANGE*2+1)*(MAXVISRANGE*2+1))); // for ai @@ -12990,168 +13252,163 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha // if anything nearby hears it, it might respond for (l = c->map->lf; l ; l = l->next) { int dist; + int difficulty; + int lbonus; + if (l == noisemaker) continue; // ie. if this lf is in the process of swapping places if (!l->cell) continue; - // if you make a noise while swapping position with - // something, its ->cell will be null here! dist = getcelldist(l->cell, c); - if (l != noisemaker) { - int difficulty; - int lbonus; - //if (canhear(l, c) && haslos(l, c)) { + // listen check difficulty is based on sound distance vs max hearing distance + if (nt == NC_SPEECH) { + // you always hear it, as long as you're in range + difficulty = 0; + } else { + //difficulty = (int) ( ((float)getcelldist(l->cell, c) / (float)gethearingrange(l)) * 20); + difficulty = (int) ( ((float)getcelldist(l->cell, c) / ((float)gethearingrange(l) + volume)) * 20); + } + // listen bonus is the sound volume + lbonus = volume; + if (lfhasflag(l, F_ASLEEP)) { + lbonus -= 5; + limit(&lbonus, 0, NA); + } - // listen check difficulty is based on sound distance vs max hearing distance - if (nt == NC_SPEECH) { - // you always hear it, as long as you're in range - difficulty = 0; - } else { - //difficulty = (int) ( ((float)getcelldist(l->cell, c) / (float)gethearingrange(l)) * 20); - difficulty = (int) ( ((float)getcelldist(l->cell, c) / ((float)gethearingrange(l) + volume)) * 20); - } + // skillcheck to hear this + if ( (isplayer(l) && haslos(l, c)) || // only player can "hear by seeing" + (canhear(l, c, volume) && skillcheck(l, SC_LISTEN, difficulty, lbonus)) ) { + flag_t *f; + // announce? + if (isplayer(l) && !lfhasflag(l, F_ASLEEP)) { + // never say "you hear xxx" if you can see the lf that caused the noise. + if (noisemaker && cansee(l, noisemaker)) { + if (seetext) { + char lfname[BUFLEN]; + getlfname(noisemaker, lfname); + msg("%s %s.", lfname, seetext); + rv = B_TRUE; + } + } else if (text && ((nt == NC_SPEECH) || !lfhasflag(l, F_DONELISTEN))) { + char textnopunc[BUFLEN]; + char punc; + int dist; - // listen bonus is the sound volume - lbonus = volume; - if (lfhasflag(l, F_ASLEEP)) { - lbonus -= 5; - limit(&lbonus, 0, NA); - } + //punc = text[strlen(text)-1]; + //strncpy(textnopunc, text, strlen(text)-1); + strcpy(textnopunc, text); + punc = textnopunc[strlen(textnopunc)-1]; + textnopunc[strlen(textnopunc)-1] = '\0'; - // skillcheck to hear this - if ( (haslos(l, c) || - (canhear(l, c, volume) && skillcheck(l, SC_LISTEN, difficulty, lbonus)))) { - flag_t *f; - // announce? - if (isplayer(l) && !lfhasflag(l, F_ASLEEP)) { - // never say "you hear xxx" if you can see the lf that caused the noise. - if (noisemaker && cansee(l, noisemaker)) { - if (seetext) { - char lfname[BUFLEN]; - getlfname(noisemaker, lfname); - msg("%s %s.", lfname, seetext); - rv = B_TRUE; + dist = getcelldist(l->cell, c); + + // listen skill gives you more info about monsters + if (noisemaker) { + enum SKILLLEVEL slev; + char lfname[BUFLEN]; + char distbuf[BUFLEN]; + char dirbuf[BUFLEN]; + int dir; + + real_getlfnamea(noisemaker, lfname, B_FALSE); + if (dist >= 20) { + strcpy(distbuf, " far away"); + } else if (dist >= 10) { + strcpy(distbuf, ""); + } else if (dist >= 5) { + strcpy(distbuf, " nearby"); + } else { + strcpy(distbuf, " very nearby"); } - } else if (text && ((nt == NC_SPEECH) || !lfhasflag(l, F_DONELISTEN))) { - char textnopunc[BUFLEN]; - char punc; - int dist; - //punc = text[strlen(text)-1]; - //strncpy(textnopunc, text, strlen(text)-1); - strcpy(textnopunc, text); - punc = textnopunc[strlen(textnopunc)-1]; - textnopunc[strlen(textnopunc)-1] = '\0'; - - dist = getcelldist(l->cell, c); - - // listen skill gives you more info about monsters - if (noisemaker) { - enum SKILLLEVEL slev; - char lfname[BUFLEN]; - char distbuf[BUFLEN]; - char dirbuf[BUFLEN]; - int dir; - - real_getlfnamea(noisemaker, lfname, B_FALSE); - if (dist >= 20) { - strcpy(distbuf, " far away"); - } else if (dist >= 10) { - strcpy(distbuf, ""); - } else if (dist >= 5) { - strcpy(distbuf, " nearby"); + dir = getdirtowards(l->cell, c, NULL, B_FALSE, DT_COMPASS); + strcpy(dirbuf, getdirname(dir)); + dirbuf[0] = tolower(dirbuf[0]); + + slev = getskill(l, SK_LISTEN); + // + // high listen skill lets you know more info. + // + // beginner = distance + // adept = distance and direction + // expert = monstername and distance and direction + // master = temporary scan of where they are! + if (slev >= PR_MASTER) { + flag_t *f; + f = lfhasflagval(l, F_CANHEARLF, noisemaker->id, NA, NA, NULL); + if (f) { + if (f->lifetime > 0) f->lifetime = 2; } else { - strcpy(distbuf, " very nearby"); - } - - dir = getdirtowards(l->cell, c, NULL, B_FALSE, DT_COMPASS); - strcpy(dirbuf, getdirname(dir)); - dirbuf[0] = tolower(dirbuf[0]); - - slev = getskill(l, SK_LISTEN); - // - // high listen skill lets you know more info. - // - // beginner = distance - // adept = distance and direction - // expert = monstername and distance and direction - // master = temporary scan of where they are! - if (slev >= PR_MASTER) { - flag_t *f; - f = lfhasflagval(l, F_CANHEARLF, noisemaker->id, NA, NA, NULL); - if (f) { - if (f->lifetime > 0) f->lifetime = 2; - } else { - addtempflag(l->flags, F_CANHEARLF, noisemaker->id, NA, NA, NULL, 2); - } - } else if (slev >= PR_EXPERT) { - msg("You hear %s%s to the %s%c", lfname, distbuf, dirbuf, punc); - rv = B_TRUE; - } else if (slev >= PR_ADEPT) { - msg("You hear %s%s to the %s%c", textnopunc, distbuf, dirbuf, punc); - rv = B_TRUE; - } else if (slev >= PR_BEGINNER) { - msg("You hear %s%s%c", textnopunc, distbuf, punc); - rv = B_TRUE; - } else { - msg("You hear %s", text); - rv = B_TRUE; + addtempflag(l->flags, F_CANHEARLF, noisemaker->id, NA, NA, NULL, 2); } + } else if (slev >= PR_EXPERT) { + msg("You hear %s%s to the %s%c", lfname, distbuf, dirbuf, punc); + rv = B_TRUE; + } else if (slev >= PR_ADEPT) { + msg("You hear %s%s to the %s%c", textnopunc, distbuf, dirbuf, punc); + rv = B_TRUE; + } else if (slev >= PR_BEGINNER) { + msg("You hear %s%s%c", textnopunc, distbuf, punc); + rv = B_TRUE; } else { msg("You hear %s", text); rv = B_TRUE; } - // only hear one thing per turn. - if (isplayer(l)) { - addflag(l->flags, F_DONELISTEN, B_TRUE, NA, NA, NULL); - practice(l, SK_LISTEN, 1); - } + } else { + msg("You hear %s", text); + rv = B_TRUE; + } + // only hear one thing per turn. + if (isplayer(l)) { + addflag(l->flags, F_DONELISTEN, B_TRUE, NA, NA, NULL); + practice(l, SK_LISTEN, 1); } } - // wake up a little - f = lfhasflag(l, F_ASLEEP); - if (f) { - if (f->lifetime > 0) { // ie. temporary - timeeffectsflag(f, volume + rnd(1,3)); - } else if (f->lifetime == PERMENANT) { - if (f->val[2] == NA) { // ie asleep rather than 'resting' + } + + // wake up a little + f = lfhasflag(l, F_ASLEEP); + if (f) { + if (f->lifetime > 0) { // ie. temporary + timeeffectsflag(f, volume + rnd(1,3)); + } else if (f->lifetime == PERMENANT) { + if (f->val[2] == NA) { // ie asleep rather than 'resting' + // wake up! + if (isplayer(l)) { + msg("^wA nearby noise awakens you!"); + rv = B_TRUE; + } + killflag(f); + } else { + // ie resting on purpose via 'R' + // only wake up if the sound if very close + //if (getcelldist(c, l->cell) == 1) { + if (volume >= getcelldist(c, l->cell)) { // wake up! if (isplayer(l)) { - msg("^wA nearby noise awakens you!"); + char wakenoise[BUFLEN]; + strcpy(wakenoise, text); + wakenoise[strlen(wakenoise)-1] = '\0'; // omit punctuation + //msg("A nearby noise awakens you!"); + msg("^wThe sound of %s awakens you!", wakenoise); rv = B_TRUE; } killflag(f); - } else { - // ie resting on purpose via 'R' - // only wake up if the sound if very close - //if (getcelldist(c, l->cell) == 1) { - if (volume >= getcelldist(c, l->cell)) { - // wake up! - if (isplayer(l)) { - char wakenoise[BUFLEN]; - strcpy(wakenoise, text); - wakenoise[strlen(wakenoise)-1] = '\0'; // omit punctuation - //msg("A nearby noise awakens you!"); - msg("^wThe sound of %s awakens you!", wakenoise); - rv = B_TRUE; - } - killflag(f); - } } - // make it temporary - //f->lifetime = rnd(1,10); } + // make it temporary + //f->lifetime = rnd(1,10); + } - // still asleep? - if (lfhasflag(l, F_ASLEEP) && cansee(player, l)) { - char lfname[BUFLEN]; - getlfname(l, lfname); - msg("%s stir%s in %s slumber...", lfname, - isplayer(l) ? "" : "s", - isplayer(l) ? "your" : "its"); - } + // still asleep? + if (lfhasflag(l, F_ASLEEP) && cansee(player, l)) { + char lfname[BUFLEN]; + getlfname(l, lfname); + msg("%s stir%s in %s slumber...", lfname, + isplayer(l) ? "" : "s", + isplayer(l) ? "your" : "its"); } } } @@ -14877,7 +15134,8 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r roll = rolldie(1, 20); if (db) { - sprintf(mbuf, "%s skillcheck - need %d, got %d(rll)+%d(attr)+%d(lvm)+%d(othmod)+%d(mod)=",lf->race->name, diff, roll, attrib,levmod, othermod,mod); + sprintf(mbuf, "%s skillcheck (%d) - need %d, got %d(rll)+%d(attr)+%d(lvm)+%d(othmod)+%d(mod)=",lf->race->name, + ct, diff, roll, attrib,levmod, othermod,mod); } modroll = roll; modroll += attrib; diff --git a/lf.h b/lf.h index e5cfd52..f1e774c 100644 --- a/lf.h +++ b/lf.h @@ -22,7 +22,7 @@ void autoweild(lifeform_t *lf); int appearsrandomly(enum RACE rid); void awardxpfor(lifeform_t *killed, float pct); void bleed(lifeform_t *lf); -void breakallgrabs(lifeform_t *lf); +void breakgrabs(lifeform_t *lf, int fromme, int tome); long calcscore(lifeform_t *lf); int calcxp(lifeform_t *lf); int calcxprace(enum RACE rid); @@ -145,6 +145,10 @@ int getmaxmp(lifeform_t *lf); float getmaxpushweight(lifeform_t *lf); int getmr(lifeform_t *lf); int getvisrange(lifeform_t *lf); +void idxtoxy(lifeform_t *lf, int idx, int *x, int *y); +void setviscell(lifeform_t *lf, cell_t *cell, int how); +int getviscell(lifeform_t *lf, cell_t *cell); +int xytoidx(lifeform_t *lf, int x, int y); int getmovespeed(lifeform_t *lf); char *getmoveverb(lifeform_t *lf); char *getmoveverbother(lifeform_t *lf); diff --git a/map.c b/map.c index 02b52d4..9b1cae9 100644 --- a/map.c +++ b/map.c @@ -2033,7 +2033,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex enum HABITAT habitat; regionthing_t *thing[MAXOUTLINETHINGS]; int nthings = 0; - int db = B_TRUE; + int db = B_FALSE; // determine habitat based on region // note: we might override this later based on our region outline @@ -2505,7 +2505,7 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r int w,h,x,y; int xmargin = 0,ymargin = 0; int minx,miny,maxx,maxy; - int db = B_TRUE; + int db = B_FALSE; int rotation = 0; flag_t *f; diff --git a/move.c b/move.c index bb006e6..55e2651 100644 --- a/move.c +++ b/move.c @@ -695,7 +695,7 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc howfar *= 2; } - breakallgrabs(lf); + breakgrabs(lf, B_TRUE, B_TRUE); for (i = 0; i < howfar; i++) { if (moveclear(lf, dir, &reason)) { @@ -983,11 +983,18 @@ int movelf(lifeform_t *lf, cell_t *newcell) { // update new cell newcell->lf = lf; + /* // update light if (lfproduceslight(lf) || (changedlev && isplayer(lf))) { calclight(lf->cell->map); precalclos(lf); } + */ + // update light + if (lfproduceslight(lf)) { + calclight(lf->cell->map); + } + precalclos(lf); if (isplayer(lf) || cansee(player, lf)) { needredraw = B_TRUE; @@ -1150,6 +1157,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) { // ISNT a vault, reveal it. // + /* if ((getskill(lf, SK_CARTOGRAPHY) >= PR_NOVICE) && (!lf->cell->vault)) { if ((postroom > 0) && (postroom != preroom)) { cell_t *c[MAX_MAPW*MAX_MAPH]; @@ -1176,6 +1184,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) { } } + */ } // does anyone else see you? diff --git a/nexus.c b/nexus.c index 2798c36..c28bb77 100644 --- a/nexus.c +++ b/nexus.c @@ -379,6 +379,7 @@ int main(int argc, char **argv) { // show level (if required) //if (haslos(player, curmap->lf->cell)) { drawscreen(); + //dblog("**** END of turn, numdraws = %d", numdraws); diff --git a/spell.c b/spell.c index 6e3297b..184cf6a 100644 --- a/spell.c +++ b/spell.c @@ -4028,7 +4028,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_GASEOUSFORM) { if (!target) target = caster; - if (hasmr(target) && (target->race->id != R_VAMPIRE) && skillcheck(target, SC_RESISTMAG, 20 + power, 0)) { + if (getmr(target) && (target->race->id != R_VAMPIRE) && skillcheck(target, SC_RESISTMAG, 20 + power, 0)) { if (isplayer(target)) { msg("You feel momentarily insubstantial."); if (seenbyplayer) *seenbyplayer = B_TRUE; @@ -5822,7 +5822,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ f = addtempflag(target->flags, F_NONCORPOREAL, B_TRUE, NA, NA, NULL, howlong); f->obfrom = OT_S_PASSWALL; - breakallgrabs(caster); + breakgrabs(target, B_TRUE, B_TRUE); } else if (spellid == OT_S_POLYMORPH) { race_t *r = NULL; flag_t *f; @@ -5930,6 +5930,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (haslos(player, target->cell)) { if (seenbyplayer) *seenbyplayer = B_TRUE; } + breakgrabs(target, B_TRUE, B_TRUE); } else { fizzle(caster); return B_TRUE; diff --git a/vaults/monsterzoo.vlt b/vaults/monsterzoo.vlt index e4c47bb..b95edf0 100644 --- a/vaults/monsterzoo.vlt +++ b/vaults/monsterzoo.vlt @@ -1,7 +1,7 @@ ! filled with random monsters @id:monsterzoo @map -random(4,4) +random(3,3,5,5) @end @legend