From f31222e47d51e35dbb0a58974789c28f00468f3d Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Fri, 9 Dec 2011 03:39:57 +0000 Subject: [PATCH] - [+] 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) --- defs.h | 6 ++++-- lf.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++------ lf.h | 1 + map.c | 24 +++++++++++++++++------- objects.c | 1 + spell.c | 7 ++++++- 6 files changed, 77 insertions(+), 16 deletions(-) diff --git a/defs.h b/defs.h index 0c2b7ec..335c38e 100644 --- a/defs.h +++ b/defs.h @@ -3428,8 +3428,10 @@ typedef struct lifeform_s { int facing; // which way are we facing int losdirty; - int nlos; - cell_t **los; + int nlos; // cells which we can see + cell_t **los; + int nlosdark; // cells which we'd be able to see if they + cell_t **losdark; // were lit. //int *viscell; int visw; int visrange; diff --git a/lf.c b/lf.c index 47965ca..83aff92 100644 --- a/lf.c +++ b/lf.c @@ -9890,6 +9890,16 @@ int haslos(lifeform_t *viewer, cell_t *dest) { 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 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 a->facing = rnd(DC_N, DC_NW); a->losdirty = B_TRUE; - a->nlos = 0; //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; @@ -13093,8 +13105,9 @@ void precalclos_new(lifeform_t *lf) { int startxray,rangemod; int maxvisrange,nightvisrange; cell_t **los; + cell_t **losdark; int *blocker; - int nlos = 0,i,nn; + int nlos = 0,nlosdark = 0, i,nn; flag_t *f; int endx[MAXVISLIMIT],endy[MAXVISLIMIT]; int nendcells = 0; @@ -13103,6 +13116,7 @@ void precalclos_new(lifeform_t *lf) { //int db = B_FALSE; enum SKILLLEVEL plev; flag_t *missingeye; + long allocamt; if (lf->cell->type->id == CT_FAKE) return; @@ -13119,10 +13133,16 @@ void precalclos_new(lifeform_t *lf) { if (lf->los) { free(lf->los); lf->los = NULL; } + if (lf->losdark) { + free(lf->losdark); lf->losdark = NULL; + } - los = malloc( sizeof(cell_t *) * (MAX_MAPW * MAX_MAPH)); - blocker = malloc( sizeof(cell_t *) * (MAX_MAPW * MAX_MAPH)); + allocamt = ((MAXVISRANGE*2)+1) * ((MAXVISRANGE*2)+1); + los = malloc( sizeof(cell_t *) * allocamt); + losdark = malloc( sizeof(cell_t *) * allocamt); + blocker = malloc( sizeof(cell_t *) * allocamt); nlos = 0; + nlosdark = 0; maxvisrange = getvisrange(lf, B_FALSE); nightvisrange = getnightvisrange(lf); @@ -13205,6 +13225,13 @@ void precalclos_new(lifeform_t *lf) { los[nlos] = c; blocker[nlos] = keepgoing ? B_FALSE : B_TRUE; 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 @@ -13221,7 +13248,14 @@ void precalclos_new(lifeform_t *lf) { } 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(losdark); free(blocker); 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) { + // already dirty? + if (lf->losdirty) return; + lf->losdirty = B_TRUE; - if (isplayer(lf)) { + + if (lf->losdirty && isplayer(lf)) { needredraw = B_TRUE; drawscreen(); } @@ -14788,6 +14826,10 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r default: break; } } + if (lfhasflag(lf, F_RAGE) && (ct == SC_STEALTH)) { + roll = 0; + modroll = 0; + } // natural 20 will pass some checks if (roll == 20) { diff --git a/lf.h b/lf.h index 70ed3ac..12177eb 100644 --- a/lf.h +++ b/lf.h @@ -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_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 haslosdark(lifeform_t *viewer, cell_t *dest); int haslos_fast(lifeform_t *viewer, cell_t *dest); void interrupt(lifeform_t *lf); enum FLAG isairborne(lifeform_t *lf); diff --git a/map.c b/map.c index 1cec371..50f281f 100644 --- a/map.c +++ b/map.c @@ -1595,6 +1595,7 @@ void calclight(map_t *map) { } } } + /* // did any lit values within player's los change? if (gamemode == GM_GAMESTARTED) { int dolos = B_FALSE; @@ -1608,6 +1609,7 @@ void calclight(map_t *map) { setlosdirty(player); } } + */ } 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 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_PIT, "Pit", H_PIT, 1, 1, D_DOWN, 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) { + enum LIGHTLEV origlit; + // don't override permenant light with temp light! //if ((c->lit == L_PERMLIGHT) && (how == L_TEMP)) { if (how == L_TEMP) { @@ -5753,21 +5757,27 @@ void makelit(cell_t *c, enum LIGHTLEV how, int howlong) { return; } } + + origlit = c->lit; + if (howlong > 0) { // TODO: use a stack here instead c->origlit = c->lit; c->origlittimer = c->littimer; c->littimer = howlong; } - if ((gamemode == GM_GAMESTARTED) && (c->lit != how)) { - lifeform_t *lf; - for (lf = c->map->lf ; lf ; lf = lf->next) { - if (haslos(lf, c)) { - setlosdirty(lf); + c->lit = how; + + if (how != origlit) { + if ((gamemode == GM_GAMESTARTED) && (c->lit != how)) { + lifeform_t *lf; + for (lf = c->map->lf ; lf ; lf = lf->next) { + if (haslos(lf, c) || haslosdark(lf, c)) { + setlosdirty(lf); + } } } } - c->lit = how; } void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong) { diff --git a/objects.c b/objects.c index 5a7349c..1ea128c 100644 --- a/objects.c +++ b/objects.c @@ -4600,6 +4600,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan if (f) { skill_t *sk; sk = findskill(f->val[0]); + assert(sk); strcat(basename, " of "); strcat(basename, sk->name); } diff --git a/spell.c b/spell.c index 75b17e9..240a050 100644 --- a/spell.c +++ b/spell.c @@ -10678,6 +10678,7 @@ int spellisfromschool(int spellid, enum SPELLSCHOOL school) { // returns true if the spell was resisted. int spellresisted(lifeform_t *target, lifeform_t *caster, int spellid, int power, int *seenbyplayer, int announce) { char text[BUFLEN],buf[BUFLEN]; + int bonus = 0; // cannot resist spells from gods when they are on their home plane 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 (announce) { msg("%s",text);