- [+] all torches are broken!!! i'm not setting losdirty when a cell's

light level changes
    - [+] try implementing "haslosdark"
    - [+] TEST TEST TEST - at the moment this is causing massive
          amounts of redraws!!!
- don't announce sounds when we can see the source (but monsters still hear them)
This commit is contained in:
Rob Pearce 2011-12-09 03:39:57 +00:00
parent 0f99007c2a
commit f31222e47d
6 changed files with 77 additions and 16 deletions

4
defs.h
View File

@ -3428,8 +3428,10 @@ typedef struct lifeform_s {
int facing; // which way are we facing int facing; // which way are we facing
int losdirty; int losdirty;
int nlos; int nlos; // cells which we can see
cell_t **los; cell_t **los;
int nlosdark; // cells which we'd be able to see if they
cell_t **losdark; // were lit.
//int *viscell; //int *viscell;
int visw; int visw;
int visrange; int visrange;

52
lf.c
View File

@ -9890,6 +9890,16 @@ int haslos(lifeform_t *viewer, cell_t *dest) {
return B_TRUE; return B_TRUE;
} }
int haslosdark(lifeform_t *viewer, cell_t *dest) {
int i;
for (i = 0; i < viewer->nlosdark; i++) {
if (viewer->losdark[i] == dest) {
return B_TRUE;
}
}
return B_FALSE;
}
int haslos_fast(lifeform_t *viewer, cell_t *dest) { int haslos_fast(lifeform_t *viewer, cell_t *dest) {
int i; int i;
for (i = 0; i < viewer->nlos; i++) { for (i = 0; i < viewer->nlos; i++) {
@ -10566,9 +10576,11 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) {
// for precalcing line of sight // for precalcing line of sight
a->facing = rnd(DC_N, DC_NW); a->facing = rnd(DC_N, DC_NW);
a->losdirty = B_TRUE; a->losdirty = B_TRUE;
a->nlos = 0;
//a->los = malloc( sizeof(cell_t *) * ((MAXVISRANGE*2+1)*(MAXVISRANGE*2+1))); //a->los = malloc( sizeof(cell_t *) * ((MAXVISRANGE*2+1)*(MAXVISRANGE*2+1)));
a->los = NULL; // will be alloced in precalclos a->los = NULL; // will be alloced in precalclos
a->losdark = NULL; // will be alloced in precalclos
a->nlos = 0;
a->nlosdark = 0;
a->eyeadjustment = 0; a->eyeadjustment = 0;
@ -13093,8 +13105,9 @@ void precalclos_new(lifeform_t *lf) {
int startxray,rangemod; int startxray,rangemod;
int maxvisrange,nightvisrange; int maxvisrange,nightvisrange;
cell_t **los; cell_t **los;
cell_t **losdark;
int *blocker; int *blocker;
int nlos = 0,i,nn; int nlos = 0,nlosdark = 0, i,nn;
flag_t *f; flag_t *f;
int endx[MAXVISLIMIT],endy[MAXVISLIMIT]; int endx[MAXVISLIMIT],endy[MAXVISLIMIT];
int nendcells = 0; int nendcells = 0;
@ -13103,6 +13116,7 @@ void precalclos_new(lifeform_t *lf) {
//int db = B_FALSE; //int db = B_FALSE;
enum SKILLLEVEL plev; enum SKILLLEVEL plev;
flag_t *missingeye; flag_t *missingeye;
long allocamt;
if (lf->cell->type->id == CT_FAKE) return; if (lf->cell->type->id == CT_FAKE) return;
@ -13119,10 +13133,16 @@ void precalclos_new(lifeform_t *lf) {
if (lf->los) { if (lf->los) {
free(lf->los); lf->los = NULL; free(lf->los); lf->los = NULL;
} }
if (lf->losdark) {
free(lf->losdark); lf->losdark = NULL;
}
los = malloc( sizeof(cell_t *) * (MAX_MAPW * MAX_MAPH)); allocamt = ((MAXVISRANGE*2)+1) * ((MAXVISRANGE*2)+1);
blocker = malloc( sizeof(cell_t *) * (MAX_MAPW * MAX_MAPH)); los = malloc( sizeof(cell_t *) * allocamt);
losdark = malloc( sizeof(cell_t *) * allocamt);
blocker = malloc( sizeof(cell_t *) * allocamt);
nlos = 0; nlos = 0;
nlosdark = 0;
maxvisrange = getvisrange(lf, B_FALSE); maxvisrange = getvisrange(lf, B_FALSE);
nightvisrange = getnightvisrange(lf); nightvisrange = getnightvisrange(lf);
@ -13205,6 +13225,13 @@ void precalclos_new(lifeform_t *lf) {
los[nlos] = c; los[nlos] = c;
blocker[nlos] = keepgoing ? B_FALSE : B_TRUE; blocker[nlos] = keepgoing ? B_FALSE : B_TRUE;
nlos++; nlos++;
} else {
// if cell WASNT lit, add it to an array of dark "visible" cells
// (lf->darklos)
// that way we can check for these to determine whether we need to recalc our los
// when light changes.
losdark[nlosdark] = c;
nlosdark++;
} }
} }
} else { // ie. if !c } else { // ie. if !c
@ -13221,7 +13248,14 @@ void precalclos_new(lifeform_t *lf) {
} }
lf->nlos = nlos; lf->nlos = nlos;
lf->losdark = malloc(sizeof(cell_t *) * nlosdark);
for (i = 0; i < nlosdark; i++) {
lf->losdark[i] = losdark[i];
}
lf->nlosdark = nlosdark;
free(los); free(los);
free(losdark);
free(blocker); free(blocker);
if (isplayer(lf) && (gamemode == GM_GAMESTARTED)) { if (isplayer(lf) && (gamemode == GM_GAMESTARTED)) {
@ -14447,8 +14481,12 @@ int setlfmaterial(lifeform_t *lf, enum MATERIAL id, int wantannounce) {
} }
void setlosdirty(lifeform_t *lf) { void setlosdirty(lifeform_t *lf) {
// already dirty?
if (lf->losdirty) return;
lf->losdirty = B_TRUE; lf->losdirty = B_TRUE;
if (isplayer(lf)) {
if (lf->losdirty && isplayer(lf)) {
needredraw = B_TRUE; needredraw = B_TRUE;
drawscreen(); drawscreen();
} }
@ -14788,6 +14826,10 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r
default: break; default: break;
} }
} }
if (lfhasflag(lf, F_RAGE) && (ct == SC_STEALTH)) {
roll = 0;
modroll = 0;
}
// natural 20 will pass some checks // natural 20 will pass some checks
if (roll == 20) { if (roll == 20) {

1
lf.h
View File

@ -267,6 +267,7 @@ flag_t *hasactivespell(lifeform_t *lf, enum OBTYPE sid);
int haslof(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest); int haslof(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest);
int haslof_real(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest, lifeform_t *srclf); int haslof_real(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest, lifeform_t *srclf);
int haslos(lifeform_t *viewer, cell_t *dest); int haslos(lifeform_t *viewer, cell_t *dest);
int haslosdark(lifeform_t *viewer, cell_t *dest);
int haslos_fast(lifeform_t *viewer, cell_t *dest); int haslos_fast(lifeform_t *viewer, cell_t *dest);
void interrupt(lifeform_t *lf); void interrupt(lifeform_t *lf);
enum FLAG isairborne(lifeform_t *lf); enum FLAG isairborne(lifeform_t *lf);

16
map.c
View File

@ -1595,6 +1595,7 @@ void calclight(map_t *map) {
} }
} }
} }
/*
// did any lit values within player's los change? // did any lit values within player's los change?
if (gamemode == GM_GAMESTARTED) { if (gamemode == GM_GAMESTARTED) {
int dolos = B_FALSE; int dolos = B_FALSE;
@ -1608,6 +1609,7 @@ void calclight(map_t *map) {
setlosdirty(player); setlosdirty(player);
} }
} }
*/
} }
int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int *by, int force) { int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int *by, int force) {
@ -5167,7 +5169,7 @@ void initmap(void) {
// region types // region types
addregiontype(RG_WORLDMAP, "World map", H_FOREST, 10, 0, D_NONE, B_TRUE); addregiontype(RG_WORLDMAP, "World map", H_FOREST, 10, 0, D_NONE, B_TRUE);
addregiontype(RG_FIRSTDUNGEON, "First Dungeon", H_DUNGEON, 10, 3, D_DOWN, B_TRUE); addregiontype(RG_FIRSTDUNGEON, "First Dungeon", H_DUNGEON, 25, 3, D_DOWN, B_TRUE);
addregiontype(RG_HEAVEN, "Realm of Gods", H_HEAVEN, 1, 0, D_NONE, B_FALSE); addregiontype(RG_HEAVEN, "Realm of Gods", H_HEAVEN, 1, 0, D_NONE, B_FALSE);
addregiontype(RG_PIT, "Pit", H_PIT, 1, 1, D_DOWN, B_FALSE); addregiontype(RG_PIT, "Pit", H_PIT, 1, 1, D_DOWN, B_FALSE);
addregiontype(RG_SEWER, "Sewer", H_SEWER, 1, 0, D_NONE, B_FALSE); addregiontype(RG_SEWER, "Sewer", H_SEWER, 1, 0, D_NONE, B_FALSE);
@ -5740,6 +5742,8 @@ void makedoor(cell_t *cell, int openchance) {
void makelit(cell_t *c, enum LIGHTLEV how, int howlong) { void makelit(cell_t *c, enum LIGHTLEV how, int howlong) {
enum LIGHTLEV origlit;
// don't override permenant light with temp light! // don't override permenant light with temp light!
//if ((c->lit == L_PERMLIGHT) && (how == L_TEMP)) { //if ((c->lit == L_PERMLIGHT) && (how == L_TEMP)) {
if (how == L_TEMP) { if (how == L_TEMP) {
@ -5753,21 +5757,27 @@ void makelit(cell_t *c, enum LIGHTLEV how, int howlong) {
return; return;
} }
} }
origlit = c->lit;
if (howlong > 0) { if (howlong > 0) {
// TODO: use a stack here instead // TODO: use a stack here instead
c->origlit = c->lit; c->origlit = c->lit;
c->origlittimer = c->littimer; c->origlittimer = c->littimer;
c->littimer = howlong; c->littimer = howlong;
} }
c->lit = how;
if (how != origlit) {
if ((gamemode == GM_GAMESTARTED) && (c->lit != how)) { if ((gamemode == GM_GAMESTARTED) && (c->lit != how)) {
lifeform_t *lf; lifeform_t *lf;
for (lf = c->map->lf ; lf ; lf = lf->next) { for (lf = c->map->lf ; lf ; lf = lf->next) {
if (haslos(lf, c)) { if (haslos(lf, c) || haslosdark(lf, c)) {
setlosdirty(lf); setlosdirty(lf);
} }
} }
} }
c->lit = how; }
} }
void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong) { void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong) {

View File

@ -4600,6 +4600,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
if (f) { if (f) {
skill_t *sk; skill_t *sk;
sk = findskill(f->val[0]); sk = findskill(f->val[0]);
assert(sk);
strcat(basename, " of "); strcat(basename, " of ");
strcat(basename, sk->name); strcat(basename, sk->name);
} }

View File

@ -10678,6 +10678,7 @@ int spellisfromschool(int spellid, enum SPELLSCHOOL school) {
// returns true if the spell was resisted. // returns true if the spell was resisted.
int spellresisted(lifeform_t *target, lifeform_t *caster, int spellid, int power, int *seenbyplayer, int announce) { int spellresisted(lifeform_t *target, lifeform_t *caster, int spellid, int power, int *seenbyplayer, int announce) {
char text[BUFLEN],buf[BUFLEN]; char text[BUFLEN],buf[BUFLEN];
int bonus = 0;
// cannot resist spells from gods when they are on their home plane // cannot resist spells from gods when they are on their home plane
if (caster && (caster->race->raceclass->id == RC_GOD)) { if (caster && (caster->race->raceclass->id == RC_GOD)) {
@ -10702,7 +10703,11 @@ int spellresisted(lifeform_t *target, lifeform_t *caster, int spellid, int power
} }
} }
} }
if (skillcheck(target, SC_RESISTMAG, getmrdiff(spellid,power), 0)) {
if ((spellid == OT_S_SLEEP) && lfhasflag(target, F_RAGE)) {
bonus += 10;
}
if (skillcheck(target, SC_RESISTMAG, getmrdiff(spellid,power), bonus)) {
if (isplayer(target) || haslos(player, target->cell)) { if (isplayer(target) || haslos(player, target->cell)) {
if (announce) { if (announce) {
msg("%s",text); msg("%s",text);