Replaced flag code with hash tables. Roughly 76% faster.

This commit is contained in:
rob 2022-08-28 16:09:49 +10:00
parent 9fcbceb8c6
commit ea1df51d08
11 changed files with 268 additions and 204 deletions

50
ai.c
View File

@ -191,7 +191,7 @@ flag_t *ai_createpathto(lifeform_t *lf, cell_t *targcell) {
char lfname[BUFLEN]; char lfname[BUFLEN];
flag_t *newf; flag_t *newf;
checkflagpile(lf->flags); // debug //checkflagpile(lf->flags); // debug
if (!db && lfhasflag(lf, F_DEBUG)) db = B_TRUE; if (!db && lfhasflag(lf, F_DEBUG)) db = B_TRUE;
@ -355,7 +355,7 @@ flag_t *ai_createpathto(lifeform_t *lf, cell_t *targcell) {
} }
} }
} }
checkflagpile(lf->flags); // debug //checkflagpile(lf->flags); // debug
// work backwards from node[cur] (ie. targcell) following parents. // work backwards from node[cur] (ie. targcell) following parents.
// populate path and return // populate path and return
@ -369,12 +369,12 @@ flag_t *ai_createpathto(lifeform_t *lf, cell_t *targcell) {
cur = cur->parent; cur = cur->parent;
} }
checkflagpile(lf->flags); // debug //checkflagpile(lf->flags); // debug
pathbuf = malloc(pathlen*6*sizeof(char)); pathbuf = malloc(pathlen*6*sizeof(char));
strcpy(pathbuf, ""); strcpy(pathbuf, "");
checkflagpile(lf->flags); // debug //checkflagpile(lf->flags); // debug
for (i = pathlen-1; i >= 0 ; i--) { for (i = pathlen-1; i >= 0 ; i--) {
char smallbuf[BUFLENTINY]; char smallbuf[BUFLENTINY];
@ -387,10 +387,10 @@ flag_t *ai_createpathto(lifeform_t *lf, cell_t *targcell) {
} }
if (db) dblog("* %s - path takes %d steps. ", lfname, pathlen); if (db) dblog("* %s - path takes %d steps. ", lfname, pathlen);
if (db) dblog("* %s - pathbuf: [%s] ", lfname, pathbuf); if (db) dblog("* %s - pathbuf: [%s] ", lfname, pathbuf);
checkflagpile(lf->flags); // debug //checkflagpile(lf->flags); // debug
newf = addflag(lf->flags, F_AIPATH, targcell->x, targcell->y, NA, pathbuf); newf = addflag(lf->flags, F_AIPATH, targcell->x, targcell->y, NA, pathbuf);
free(pathbuf); free(pathbuf);
checkflagpile(lf->flags); // debug //checkflagpile(lf->flags); // debug
return newf; return newf;
} }
@ -2362,13 +2362,13 @@ int aimovetotargetcell(lifeform_t *lf, flag_t *f) {
iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL); iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL);
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
if (lfhasflag(lf, F_DEBUG)) { if (lfhasflag(lf, F_DEBUG)) {
db = B_TRUE; db = B_TRUE;
} }
checkflagpile(lf->flags); // debug //checkflagpile(lf->flags); // debug
x = f->val[0]; x = f->val[0];
y = f->val[1]; y = f->val[1];
@ -2486,8 +2486,8 @@ int aimovetotargetcell(lifeform_t *lf, flag_t *f) {
// move randomly now. // move randomly now.
dorandommove(lf, B_NOBADMOVES, B_TRUE, B_FALSE); // this function will call rest() if we cant move dorandommove(lf, B_NOBADMOVES, B_TRUE, B_FALSE); // this function will call rest() if we cant move
} }
checkflagpile(lf->flags); // debug //checkflagpile(lf->flags); // debug
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
// success // success
return B_TRUE; return B_TRUE;
} }
@ -2562,7 +2562,7 @@ void aiturn(lifeform_t *lf) {
lifeform_t *master = NULL; lifeform_t *master = NULL;
enum ATTRBRACKET iqb; enum ATTRBRACKET iqb;
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
/* /*
if (wantdb && haslos(player, lf->cell)) { if (wantdb && haslos(player, lf->cell)) {
@ -2590,7 +2590,7 @@ void aiturn(lifeform_t *lf) {
if (db) dblog(".oO { i am not alive, skipping turn. }"); if (db) dblog(".oO { i am not alive, skipping turn. }");
taketime(lf, SPEED_DEAD); taketime(lf, SPEED_DEAD);
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
return; return;
} }
@ -2599,7 +2599,7 @@ void aiturn(lifeform_t *lf) {
if (!playerhasmoved) { if (!playerhasmoved) {
if (db) dblog(".oO { player hasn't had their initial turn yet, skipping turn. }"); if (db) dblog(".oO { player hasn't had their initial turn yet, skipping turn. }");
taketime(lf, SPEED_DEAD); taketime(lf, SPEED_DEAD);
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
return; return;
} }
@ -2615,18 +2615,18 @@ void aiturn(lifeform_t *lf) {
master = findlf(lf->cell->map, f->val[0]); master = findlf(lf->cell->map, f->val[0]);
} }
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
ailoscheck(lf); ailoscheck(lf);
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
/////////////////////////////////////////////// ///////////////////////////////////////////////
// emergencies / fixing up // emergencies / fixing up
/////////////////////////////////////////////// ///////////////////////////////////////////////
if (ai_handle_emergencies(lf, iqb)) return; if (ai_handle_emergencies(lf, iqb)) return;
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
ailoscheck(lf); ailoscheck(lf);
@ -2643,7 +2643,7 @@ void aiturn(lifeform_t *lf) {
/////////////////////////////////////////////// ///////////////////////////////////////////////
if (ai_healing(lf)) return; if (ai_healing(lf)) return;
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
ailoscheck(lf); ailoscheck(lf);
@ -2652,7 +2652,7 @@ void aiturn(lifeform_t *lf) {
/////////////////////////////////////////////// ///////////////////////////////////////////////
if (ai_inventory_mgt(lf, &icanattack)) return; if (ai_inventory_mgt(lf, &icanattack)) return;
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
ailoscheck(lf); ailoscheck(lf);
/////////////////////////////////////////////// ///////////////////////////////////////////////
@ -2660,7 +2660,7 @@ void aiturn(lifeform_t *lf) {
/////////////////////////////////////////////// ///////////////////////////////////////////////
if (ai_attack_existing_target(lf)) return; if (ai_attack_existing_target(lf)) return;
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
ailoscheck(lf); ailoscheck(lf);
/////////////////////////////////////////////// ///////////////////////////////////////////////
@ -2668,14 +2668,14 @@ void aiturn(lifeform_t *lf) {
/////////////////////////////////////////////// ///////////////////////////////////////////////
if (ai_premovement(lf)) return; if (ai_premovement(lf)) return;
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
ailoscheck(lf); ailoscheck(lf);
/////////////////////////////////////////////// ///////////////////////////////////////////////
// movement // movement
/////////////////////////////////////////////// ///////////////////////////////////////////////
if (ai_movement(lf)) return; if (ai_movement(lf)) return;
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
ailoscheck(lf); ailoscheck(lf);
/////////////////////////////////////////////// ///////////////////////////////////////////////
@ -2683,22 +2683,22 @@ void aiturn(lifeform_t *lf) {
// to attack, etc) // to attack, etc)
/////////////////////////////////////////////// ///////////////////////////////////////////////
if (ai_bored(lf, master, icanattack)) return; if (ai_bored(lf, master, icanattack)) return;
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
ailoscheck(lf); ailoscheck(lf);
// DEFAULT - try to move in a random direction // DEFAULT - try to move in a random direction
if (db) dblog(".oO { default - moving randomly }"); if (db) dblog(".oO { default - moving randomly }");
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
dorandommove(lf, B_NOBADMOVES, B_TRUE, B_FALSE); // this function will call rest() if we cant move dorandommove(lf, B_NOBADMOVES, B_TRUE, B_FALSE); // this function will call rest() if we cant move
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
ailoscheck(lf); ailoscheck(lf);
// somehow still here? // somehow still here?
if (!lf->timespent) { if (!lf->timespent) {
taketime(lf, getmovespeed(lf)); taketime(lf, getmovespeed(lf));
} }
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
} }
// is the spell 'spellid' okay for AI lifeform 'lf' to cast at 'victim', for given purpose. // is the spell 'spellid' okay for AI lifeform 'lf' to cast at 'victim', for given purpose.

6
defs.h
View File

@ -17,7 +17,7 @@
// for flags hashtable // for flags hashtable
#define NHASHBUCKETS (5) #define NHASHBUCKETS (20)
// how much your str/agi/etc goes up every few levels // how much your str/agi/etc goes up every few levels
#define STATAMTPERLEVEL 5 #define STATAMTPERLEVEL 5
@ -5319,8 +5319,8 @@ typedef struct flagpile_s {
struct object_s *ob; struct object_s *ob;
struct flag_s *first[NHASHBUCKETS],*last[NHASHBUCKETS]; struct flag_s *first[NHASHBUCKETS],*last[NHASHBUCKETS];
struct flag_s *item[MAXFLAGS]; //struct flag_s *item[MAXFLAGS];
int nitems; //int nitems;
} flagpile_t; } flagpile_t;
typedef struct altflagval_s { typedef struct altflagval_s {

97
flag.c
View File

@ -78,7 +78,7 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
int hash; int hash;
enum { NONE, FIRST, FIRST2, MIDDLE, LAST } fml = NONE; enum { NONE, FIRST, FIRST2, MIDDLE, LAST } fml = NONE;
checkflagpile(fp); //checkflagpile(fp);
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
// identified things mean all new flags are autmaticlaly known. // identified things mean all new flags are autmaticlaly known.
@ -315,7 +315,7 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
//checkflagpile(fp); //checkflagpile(fp);
updatefpindex(fp); //updatefpindex(fp);
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
@ -471,7 +471,7 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
} }
//checkflagpile(fp); //checkflagpile(fp);
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
checkflagpile(fp); //checkflagpile(fp);
return f; return f;
} }
@ -482,7 +482,7 @@ flagpile_t *addflagpile(lifeform_t *owner, object_t *ob) {
foreach_bucket(i) { foreach_bucket(i) {
fp->first[i] = NULL; fp->first[i] = NULL;
fp->last[i] = NULL; fp->last[i] = NULL;
fp->nitems = 0; //fp->nitems = 0;
} }
fp->owner = owner; fp->owner = owner;
fp->ob = ob; fp->ob = ob;
@ -528,7 +528,8 @@ void changeflagtext(flag_t *f, char *newtext) {
} }
} }
void checkflagpile_mapobs(map_t *m) { /*
void//checkflagpile_mapobs(map_t *m) {
cell_t *c; cell_t *c;
object_t *o; object_t *o;
int nbad = 0,x,y; int nbad = 0,x,y;
@ -553,15 +554,15 @@ void checkflagpile_mapobs(map_t *m) {
} }
} }
void checkflagpile_maplfs(map_t *m) { void//checkflagpile_maplfs(map_t *m) {
lifeform_t *l; lifeform_t *l;
if (!flagcheck) return; if (!flagcheck) return;
for (l = m->lf ; l ; l = l->next) { for (l = m->lf ; l ; l = l->next) {
checkflagpile(l->flags); //checkflagpile(l->flags);
} }
} }
void checkflagpile(flagpile_t *fp) { void//checkflagpile(flagpile_t *fp) {
if (!flagcheck) return; if (!flagcheck) return;
if (fpisbad(fp)) { if (fpisbad(fp)) {
assert("flagpile is corrupt!" == 0); assert("flagpile is corrupt!" == 0);
@ -569,7 +570,6 @@ void checkflagpile(flagpile_t *fp) {
} }
/// TODO: remove this function
int fpisbad(flagpile_t *fp) { int fpisbad(flagpile_t *fp) {
flag_t *f; flag_t *f;
int i; int i;
@ -592,6 +592,7 @@ int fpisbad(flagpile_t *fp) {
} }
return B_FALSE; return B_FALSE;
} }
*/
// returns # of flags copied // returns # of flags copied
@ -850,6 +851,7 @@ flag_t *hasflagknown(flagpile_t *fp, int id) {
return hasflag_real(fp, id, B_TRUE, NULL, NA); return hasflag_real(fp, id, B_TRUE, NULL, NA);
} }
/*
flag_t *flag_bsearch(flagpile_t *fp, int id, int *iterp) { flag_t *flag_bsearch(flagpile_t *fp, int id, int *iterp) {
flag_t *f,*searchfrom = NULL; flag_t *f,*searchfrom = NULL;
int pos; int pos;
@ -898,6 +900,7 @@ flag_t *flag_bsearch(flagpile_t *fp, int id, int *iterp) {
if (iterp) *iterp += iter; if (iterp) *iterp += iter;
return searchfrom; return searchfrom;
} }
*/
flag_t *flag_hsearch(flagpile_t *fp, int id, int *iterp) { flag_t *flag_hsearch(flagpile_t *fp, int id, int *iterp) {
flag_t *f,*searchfrom = NULL; flag_t *f,*searchfrom = NULL;
@ -926,7 +929,7 @@ flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown, flag_t *exception, i
if (flagdb) db = B_TRUE; if (flagdb) db = B_TRUE;
if (db) dblog("call to hasflag %d in flagpile with %d entries", id, fp->nitems); if (db) dblog("call to hasflag %d in flagpile", id);
// find first occurence of this id // find first occurence of this id
//searchfrom = flag_bsearch(fp, id, &iter); //searchfrom = flag_bsearch(fp, id, &iter);
@ -936,14 +939,16 @@ flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown, flag_t *exception, i
f = searchfrom; f = searchfrom;
//while (f && (f->id == id)) { for binary search //while (f && (f->id == id)) { for binary search
while (f) { while (f) {
int valid = B_FALSE;
if (f->id == id) { if (f->id == id) {
int valid = B_TRUE; valid = B_TRUE;
if (f == exception) valid = B_FALSE; if (f == exception) valid = B_FALSE;
if ((lifetimeexception != NA) && (f->lifetime == lifetimeexception)) valid = B_FALSE; if ((lifetimeexception != NA) && (f->lifetime == lifetimeexception)) valid = B_FALSE;
if ((wantknown != NA) && (f->known != wantknown)) valid = B_FALSE; if ((wantknown != NA) && (f->known != wantknown)) valid = B_FALSE;
if (owner && (f->lifetime == FROMJOB) && !getjob(owner)) valid = B_FALSE; if (owner && (f->lifetime == FROMJOB) && !getjob(owner)) valid = B_FALSE;
//if (owner && (f->lifetime == FROMSKILL) && !getskill(owner, xxx)) valid = B_FALSE; //if (owner && (f->lifetime == FROMSKILL) && !getskill(owner, xxx)) valid = B_FALSE;
}
if (valid) { if (valid) {
foundflag = f; foundflag = f;
break; break;
@ -952,7 +957,6 @@ flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown, flag_t *exception, i
subiter++; subiter++;
} }
} }
}
if (db) dblog("finished - %s - iter=%d, subiter=%d", foundflag ? "found it" : "NOT FOUND",iter,subiter); if (db) dblog("finished - %s - iter=%d, subiter=%d", foundflag ? "found it" : "NOT FOUND",iter,subiter);
return foundflag; return foundflag;
@ -978,7 +982,6 @@ flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown, flag_t *exception, i
return NULL; return NULL;
} }
flag_t *hasflagval(flagpile_t *fp, int id, int val1, int val2, int val3, char *text) { flag_t *hasflagval(flagpile_t *fp, int id, int val1, int val2, int val3, char *text) {
return hasflagval_real(fp, id, val1, val2, val3, text, B_FALSE, NA); // doesn't have to be known return hasflagval_real(fp, id, val1, val2, val3, text, B_FALSE, NA); // doesn't have to be known
} }
@ -999,8 +1002,6 @@ int getcounter(flagpile_t *fp) {
flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, char *text, int wantknown, int lifetimeexception) { flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, char *text, int wantknown, int lifetimeexception) {
flag_t *f,*foundflag = NULL, *searchfrom = NULL; flag_t *f,*foundflag = NULL, *searchfrom = NULL;
lifeform_t *owner; lifeform_t *owner;
int pos;
int l,r;
int iter = 0; int iter = 0;
int db = B_FALSE; int db = B_FALSE;
owner = fp->owner; owner = fp->owner;
@ -1008,52 +1009,14 @@ flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, ch
if (flagdb) db = B_TRUE; if (flagdb) db = B_TRUE;
//if (db) dblog("hasflag %d in flagpile with %d entries", id, fp->nitems); //if (db) dblog("hasflag %d in flagpile with %d entries", id, fp->nitems);
// binary search for this flag id. searchfrom = flag_hsearch(fp, id, &iter);
l = 0;
r = fp->nitems-1;
while (!searchfrom) {
//if (db) dblog(" iter#%d: l=%d,r=%d", iter, l, r);
if (r < l) {
// NOT FOUND.
//if (db) dblog(" r < l: not found!");
break;
} else if (fp->item[l]->id > id) {
// NOT FOUND.
//if (db) dblog(" leftid %d > wantid %d. not found!",fp->item[l]->id, id);
break;
} else if (fp->item[r]->id < id) {
// NOT FOUND.
//if (db) dblog(" rightid %d > wantid %d. not found!",fp->item[r]->id, id);
break;
}
// half way inbetween l and r
pos = ((l+r)/2);
f = fp->item[pos];
//if (db) dblog(" iter#%d: pos=%d. item here is %d (looking for %d)", iter, pos, f->id, id);
if (f->id == id) {
// go back to first occurence
while (f->prev && (f->prev->id == id)) {
iter++;
f = f->prev;
}
searchfrom = f;
break;
} else if (f->id > id) {
// go left
r = pos-1;
} else {
// go right
l = pos+1;
}
iter++;
}
// now find a valid one // now find a valid one
f = searchfrom; f = searchfrom;
while (f && (f->id == id)) { while (f) {
if (f->id == id) {
if ((lifetimeexception != NA) && (f->lifetime == lifetimeexception)) { if ((lifetimeexception != NA) && (f->lifetime == lifetimeexception)) {
// invalid
} else if (owner && (f->lifetime == FROMJOB) && !getjob(owner)) { } else if (owner && (f->lifetime == FROMJOB) && !getjob(owner)) {
// invalid // invalid
} else if ( ((val1 == NA) || (f->val[0] == val1)) && } else if ( ((val1 == NA) || (f->val[0] == val1)) &&
@ -1065,7 +1028,7 @@ flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, ch
break; break;
} }
} }
}
f = f->next; f = f->next;
} }
@ -1244,7 +1207,7 @@ void real_killflag(flag_t *f, int wantannounce) {
} }
} }
} }
checkflagpile(pile); //checkflagpile(pile);
if (gamemode == GM_GAMESTARTED) { if (gamemode == GM_GAMESTARTED) {
// flags which cause a redraw // flags which cause a redraw
@ -1255,7 +1218,7 @@ void real_killflag(flag_t *f, int wantannounce) {
redolos = getflagpilelocation(f->pile); redolos = getflagpilelocation(f->pile);
} }
} }
checkflagpile(pile); //checkflagpile(pile);
// notify // notify
if (gamemode == GM_GAMESTARTED) { if (gamemode == GM_GAMESTARTED) {
@ -1322,7 +1285,7 @@ void real_killflag(flag_t *f, int wantannounce) {
} }
} }
} }
checkflagpile(pile); //checkflagpile(pile);
// determine bucket // determine bucket
hash = getflaghash(f->id); hash = getflaghash(f->id);
@ -1369,10 +1332,10 @@ void real_killflag(flag_t *f, int wantannounce) {
////////////////////////////////////////// //////////////////////////////////////////
f = NULL; f = NULL;
checkflagpile(pile); //checkflagpile(pile);
// re-index the pile // re-index the pile
updatefpindex(pile); //updatefpindex(pile);
checkflagpile(pile); //checkflagpile(pile);
if (gamemode == GM_GAMESTARTED) { if (gamemode == GM_GAMESTARTED) {
for (i = 0; i < ngodlfs; i++) { for (i = 0; i < ngodlfs; i++) {
@ -1843,16 +1806,16 @@ void timeeffectsflags(flagpile_t *fp) {
timeeffectsflag(f, 1); timeeffectsflag(f, 1);
// if this checkflag() crashes, we know there we a bug during processing of // if this checkflag() crashes, we know there we a bug during processing of
// flag 'thisid' // flag 'thisid'
checkflagpile(fp); //checkflagpile(fp);
} }
} }
//checkflagpile(fp); //checkflagpile(fp);
} }
// generate an index // generate an index
/*
void updatefpindex(flagpile_t *fp) { void updatefpindex(flagpile_t *fp) {
return; return;
/*
flag_t *f; flag_t *f;
fp->nitems = 0; fp->nitems = 0;
@ -1864,5 +1827,5 @@ void updatefpindex(flagpile_t *fp) {
fp->nitems++; fp->nitems++;
assert(fp->nitems < MAXFLAGS); assert(fp->nitems < MAXFLAGS);
} }
*/
} }
*/

6
flag.h
View File

@ -11,17 +11,19 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
flagpile_t *addflagpile(lifeform_t *owner, object_t *o); flagpile_t *addflagpile(lifeform_t *owner, object_t *o);
int canbemadepermenant(enum FLAG id); int canbemadepermenant(enum FLAG id);
void changeflagtext(flag_t *f, char *newtext); void changeflagtext(flag_t *f, char *newtext);
/*
int fpisbad(flagpile_t *fp); int fpisbad(flagpile_t *fp);
void checkflagpile(flagpile_t *fp); void checkflagpile(flagpile_t *fp);
void checkflagpile_maplfs(map_t *m); void checkflagpile_maplfs(map_t *m);
void checkflagpile_mapobs(map_t *m); void checkflagpile_mapobs(map_t *m);
*/
int copyflag(flagpile_t *dst, flagpile_t *src, enum FLAG id); int copyflag(flagpile_t *dst, flagpile_t *src, enum FLAG id);
void copyflags(flagpile_t *dst, flagpile_t *src, int lifetime); void copyflags(flagpile_t *dst, flagpile_t *src, int lifetime);
int countflags(flagpile_t *fp); int countflags(flagpile_t *fp);
int countflagsofid(flagpile_t *fp, enum FLAG fid ); int countflagsofid(flagpile_t *fp, enum FLAG fid );
void dumpflags(flagpile_t *fp); void dumpflags(flagpile_t *fp);
flag_t *flag_bsearch(flagpile_t *fp, int id, int *iterp); //flag_t *flag_bsearch(flagpile_t *fp, int id, int *iterp);
flag_t *flag_hsearch(flagpile_t *fp, int id, int *iterp); flag_t *flag_hsearch(flagpile_t *fp, int id, int *iterp);
int flagcausesinterrupt(flag_t *f, enum GAINORLOSS gol); int flagcausesinterrupt(flag_t *f, enum GAINORLOSS gol);
int flagcausesloscalc(enum FLAG fid); int flagcausesloscalc(enum FLAG fid);
@ -59,4 +61,4 @@ void revealflagob(lifeform_t *lf, flag_t *f);
void sumflags(flagpile_t *fp, enum FLAG id, int *val0, int *val1, int *val2); void sumflags(flagpile_t *fp, enum FLAG id, int *val0, int *val1, int *val2);
void timeeffectsflag(flag_t *f, int howlong); void timeeffectsflag(flag_t *f, int howlong);
void timeeffectsflags(flagpile_t *fp); void timeeffectsflags(flagpile_t *fp);
void updatefpindex(flagpile_t *fp); //void updatefpindex(flagpile_t *fp);

125
lf.c
View File

@ -3328,7 +3328,7 @@ int die(lifeform_t *lf) {
int willbecomeghost = B_FALSE; int willbecomeghost = B_FALSE;
object_t *corpse = NULL; object_t *corpse = NULL;
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags; int nretflags,b;
cell_t *corpsecell; cell_t *corpsecell;
lifeform_t *killer = NULL; lifeform_t *killer = NULL;
int dobonesfile = B_FALSE; int dobonesfile = B_FALSE;
@ -4206,12 +4206,14 @@ int die(lifeform_t *lf) {
flag_t *f, *nextf; flag_t *f, *nextf;
// remove all job flags // remove all job flags
lf->born = B_FALSE; lf->born = B_FALSE;
for (f = lf->flags->first ; f ; f = nextf) { foreach_bucket(b) {
for (f = lf->flags->first[b] ; f ; f = nextf) {
nextf = f->next; nextf = f->next;
if (f->lifetime == FROMJOB) { if (f->lifetime == FROMJOB) {
killflag(f); killflag(f);
} }
} }
}
killflagsofid(lf->flags, F_JOB); killflagsofid(lf->flags, F_JOB);
lf->born = B_TRUE; lf->born = B_TRUE;
// turn into a ghost // turn into a ghost
@ -5675,12 +5677,13 @@ void enhancerandomskill(lifeform_t *lf) {
flag_t *f; flag_t *f;
enum SKILL poss[MAXSKILLS]; enum SKILL poss[MAXSKILLS];
int nposs = 0; int nposs = 0;
int sel; int sel,b;
enum SKILLLEVEL wantlev; enum SKILLLEVEL wantlev;
// enhance lower level skills first, and only up to PR_ADEPT. // enhance lower level skills first, and only up to PR_ADEPT.
for (wantlev = PR_NOVICE; wantlev <= PR_BEGINNER; wantlev++) { for (wantlev = PR_NOVICE; wantlev <= PR_BEGINNER; wantlev++) {
for (f = lf->flags->first ; f ; f = f->next) { foreach_bucket(b) {
for (f = lf->flags->first[b] ; f ; f = f->next) {
if ((f->id == F_HASSKILL) && !ismaxedskill(lf, f->val[0]) && (f->val[1] == wantlev)) { if ((f->id == F_HASSKILL) && !ismaxedskill(lf, f->val[0]) && (f->val[1] == wantlev)) {
if (isplayer(lf) && (f->val[2] != B_TRUE)) { if (isplayer(lf) && (f->val[2] != B_TRUE)) {
// for player - select only from skills which we have used since last levelup. // for player - select only from skills which we have used since last levelup.
@ -5696,6 +5699,7 @@ void enhancerandomskill(lifeform_t *lf) {
break; break;
} }
} }
}
} }
void enhanceskills(lifeform_t *lf) { void enhanceskills(lifeform_t *lf) {
@ -5708,7 +5712,7 @@ void enhanceskills(lifeform_t *lf) {
enum SKILLLEVEL slev; enum SKILLLEVEL slev;
int gainedxplev = B_FALSE; int gainedxplev = B_FALSE;
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags; int nretflags,b;
if (lf->newlevel != lf->level) { if (lf->newlevel != lf->level) {
lf->level = lf->newlevel; lf->level = lf->newlevel;
@ -5847,13 +5851,15 @@ void enhanceskills(lifeform_t *lf) {
objecttype_t *ot; objecttype_t *ot;
skillstoenhance = 0; skillstoenhance = 0;
for (f = lf->flags->first ; f ; f = f->next) { foreach_bucket(b) {
for (f = lf->flags->first[b] ; f ; f = f->next) {
if ((f->id == F_HASSKILL) && (f->val[1] != PR_MASTER)) { if ((f->id == F_HASSKILL) && (f->val[1] != PR_MASTER)) {
if (lf->skillpoints >= getskilllevcost(f->val[1] + 1)) { if (lf->skillpoints >= getskilllevcost(f->val[1] + 1)) {
skillstoenhance++; skillstoenhance++;
} }
} }
} }
}
if (lf->skillpoints >= newskillcost) { if (lf->skillpoints >= newskillcost) {
skillstolearn = 0; skillstolearn = 0;
@ -6903,9 +6909,10 @@ subjob_t *findsubjobbyletter(char letter) {
// returns true if we did somethign // returns true if we did somethign
int fixcurses(lifeform_t *lf) { int fixcurses(lifeform_t *lf) {
int donesomething = B_FALSE; int donesomething = B_FALSE,b;
flag_t *f,*nextf; flag_t *f,*nextf;
for (f = lf->flags->first ; f ; f = nextf) { foreach_bucket(b) {
for (f = lf->flags->first[b] ; f ; f = nextf) {
nextf = f->next; nextf = f->next;
if (f->id == F_LYCANTHROPE) { if (f->id == F_LYCANTHROPE) {
donesomething = B_TRUE; donesomething = B_TRUE;
@ -6925,6 +6932,7 @@ int fixcurses(lifeform_t *lf) {
continue; continue;
} }
} }
}
if (donesomething) { if (donesomething) {
if (isplayer(lf)) { if (isplayer(lf)) {
msg("^%cYour curses are lifted!", getlfcol(lf, CC_VGOOD)); msg("^%cYour curses are lifted!", getlfcol(lf, CC_VGOOD));
@ -8157,7 +8165,7 @@ int getavgdam(lifeform_t *lf, int forxp) {
int db = B_FALSE; int db = B_FALSE;
flag_t *f; flag_t *f;
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags; int nretflags,b;
if (lfhasflag(lf, F_DEBUG)) { if (lfhasflag(lf, F_DEBUG)) {
db = B_TRUE; db = B_TRUE;
@ -8182,7 +8190,8 @@ int getavgdam(lifeform_t *lf, int forxp) {
thisavg = ((float)min + (float)max) / 2.0; thisavg = ((float)min + (float)max) / 2.0;
// confers anything? // confers anything?
for (of = o->flags->first ; of ; of = of->next) { foreach_bucket(b) {
for (of = o->flags->first[b] ; of ; of = of->next) {
if (of->id == F_HITCONFER) { if (of->id == F_HITCONFER) {
flag_t *valflag; flag_t *valflag;
int maxlifetime; int maxlifetime;
@ -8202,6 +8211,7 @@ int getavgdam(lifeform_t *lf, int forxp) {
} }
} }
} }
}
// modify for accuracy // modify for accuracy
acc = getlfaccuracy(lf, o); acc = getlfaccuracy(lf, o);
@ -8233,11 +8243,13 @@ int getavgdam(lifeform_t *lf, int forxp) {
thisavg = ((float)min + (float)max) / 2.0; thisavg = ((float)min + (float)max) / 2.0;
// confers anything? // confers anything?
for (of = o->flags->first ; of ; of = of->next) { foreach_bucket(b) {
for (of = o->flags->first[b] ; of ; of = of->next) {
if (of->id == F_HITCONFER) { if (of->id == F_HITCONFER) {
thisavg += 10; thisavg += 10;
} }
} }
}
// modify for accuracy // modify for accuracy
acc = getlfaccuracy(lf, o); acc = getlfaccuracy(lf, o);
@ -9043,7 +9055,7 @@ char *getjobname(lifeform_t *lf) {
int getjobrecommendation(race_t *r, job_t *j) { int getjobrecommendation(race_t *r, job_t *j) {
int rec = 0; int rec = 0;
flag_t *retflag[MAXCANDIDATES],*jobflag,*f; flag_t *retflag[MAXCANDIDATES],*jobflag,*f;
int nretflags,i; int nretflags,i,b;
getflags(r->flags, retflag, &nretflags, F_STARTATT, F_STARTSKILL, F_NOSPELLS, F_NOSKILL, F_MPMOD, F_DTIMMUNE, F_DTRESIST, F_RESISTMAG, F_MPDICE, F_ARMOURRATING, F_NONE); getflags(r->flags, retflag, &nretflags, F_STARTATT, F_STARTSKILL, F_NOSPELLS, F_NOSKILL, F_MPMOD, F_DTIMMUNE, F_DTRESIST, F_RESISTMAG, F_MPDICE, F_ARMOURRATING, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
@ -9078,11 +9090,13 @@ int getjobrecommendation(race_t *r, job_t *j) {
} }
} }
} else if (f->id == F_ARMOURRATING) { } else if (f->id == F_ARMOURRATING) {
for (jobflag = j->flags->first ; jobflag ; jobflag = jobflag->next) { foreach_bucket(b) {
for (jobflag = j->flags->first[b] ; jobflag ; jobflag = jobflag->next) {
if ((jobflag->id == F_STARTSKILL) && isweaponskill(jobflag->val[0])) { if ((jobflag->id == F_STARTSKILL) && isweaponskill(jobflag->val[0])) {
rec += 1; rec += 1;
} }
} }
}
} else if ((f->id == F_DTIMMUNE) || (f->id == F_DTRESIST)) { } else if ((f->id == F_DTIMMUNE) || (f->id == F_DTRESIST)) {
if (hasflag(j->flags, f->id)) { if (hasflag(j->flags, f->id)) {
rec += 2; rec += 2;
@ -9107,11 +9121,13 @@ int getjobrecommendation(race_t *r, job_t *j) {
} }
// race can't have spells, and job has a magic skill? // race can't have spells, and job has a magic skill?
// (SLOW search) // (SLOW search)
for (jobflag = j->flags->first ; jobflag ; jobflag = jobflag->next) { foreach_bucket(b) {
for (jobflag = j->flags->first[b] ; jobflag ; jobflag = jobflag->next) {
if ((jobflag->id == F_STARTSKILL) && isspellskill(jobflag->val[0])) { if ((jobflag->id == F_STARTSKILL) && isspellskill(jobflag->val[0])) {
rec -= 2; rec -= 2;
} }
} }
}
// job uses mp? // job uses mp?
if (hasflag(j->flags, F_MPDICE)) { if (hasflag(j->flags, F_MPDICE)) {
rec -= 4; rec -= 4;
@ -12133,7 +12149,7 @@ void givebehaviour(lifeform_t *lf, enum BEHAVIOUR bid) {
void givejob(lifeform_t *lf, enum JOB jobid) { void givejob(lifeform_t *lf, enum JOB jobid) {
job_t *j; job_t *j;
flag_t *f; flag_t *f;
int i; int i,b;
//int rollhp = B_FALSE; //int rollhp = B_FALSE;
int rollmp = B_FALSE; int rollmp = B_FALSE;
int rollatt[MAXATTS]; int rollatt[MAXATTS];
@ -12194,7 +12210,8 @@ void givejob(lifeform_t *lf, enum JOB jobid) {
// - hpmod ones // - hpmod ones
// - skills which we already have f_noskill for. // - skills which we already have f_noskill for.
// - alignment (in the case of monsters) // - alignment (in the case of monsters)
for (f = j->flags->first ; f ; f = f->next) { foreach_bucket(b) {
for (f = j->flags->first[b] ; f ; f = f->next) {
int val[3],id,ignorethis = B_FALSE; int val[3],id,ignorethis = B_FALSE;
char *text; char *text;
flag_t *f2; flag_t *f2;
@ -12257,6 +12274,7 @@ void givejob(lifeform_t *lf, enum JOB jobid) {
} }
} }
} }
}
// now give start obs/skills from the job // now give start obs/skills from the job
givestartskills(lf, lf->flags); givestartskills(lf, lf->flags);
@ -12576,7 +12594,7 @@ void giveobflags(lifeform_t *lf, object_t *o, enum FLAG whattype) {
flag_t *f,*newflag; flag_t *f,*newflag;
int held = B_FALSE, equipped = B_FALSE,activated = B_FALSE; int held = B_FALSE, equipped = B_FALSE,activated = B_FALSE;
int lifetimeval; int lifetimeval,b;
if (gettechlevel(o->type->id) > getskill(lf, SK_TECHUSAGE)) { if (gettechlevel(o->type->id) > getskill(lf, SK_TECHUSAGE)) {
return; return;
@ -12624,7 +12642,8 @@ void giveobflags(lifeform_t *lf, object_t *o, enum FLAG whattype) {
assert(1 == 0); assert(1 == 0);
} }
for (f = o->flags->first ; f ; f = f->next) { foreach_bucket(b) {
for (f = o->flags->first[b] ; f ; f = f->next) {
if (f->id == whattype) { if (f->id == whattype) {
int known = B_FALSE; int known = B_FALSE;
int addit = B_FALSE; int addit = B_FALSE;
@ -12670,6 +12689,7 @@ void giveobflags(lifeform_t *lf, object_t *o, enum FLAG whattype) {
} }
} }
} }
}
// if all conferred flags now known, object is known // if all conferred flags now known, object is known
if (flagsfound && (flagsknown == flagsfound) && !isknown(o)) { if (flagsfound && (flagsknown == flagsfound) && !isknown(o)) {
@ -13062,7 +13082,7 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
cell_t *mapcell; cell_t *mapcell;
enum LFSIZE maxobsize = SZ_MAX; enum LFSIZE maxobsize = SZ_MAX;
int isshop = B_FALSE; int isshop = B_FALSE;
int depthmod2 = 0; int depthmod2 = 0,b;
cell_t fakecell; cell_t fakecell;
map_t fakemap; map_t fakemap;
@ -13210,7 +13230,8 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
killfakes(&fakemap, &fakecell); killfakes(&fakemap, &fakecell);
// give start objects and id them // give start objects and id them
for (f = fp->first ; f ; f = f->next) { foreach_bucket(b) {
for (f = fp->first[b] ; f ; f = f->next) {
int val[3]; int val[3];
int id; int id;
char *text; char *text;
@ -13471,14 +13492,17 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
} }
} else if (isshop) { } else if (isshop) {
flag_t *f2; flag_t *f2;
int b2;
// all flags are known // all flags are known
for (f2 = o->flags->first ; f2; f2 = f2->next) { foreach_bucket(b2) {
for (f2 = o->flags->first[b2] ; f2; f2 = f2->next) {
f2->known = B_TRUE; f2->known = B_TRUE;
} }
} }
}
} // end if o } // end if o
} // end foreach container flag } // end foreach container flag
} // end foreach bucket
// now remove startob flags so we don't get them again! // now remove startob flags so we don't get them again!
killflagsofid(fp, F_STARTOB); killflagsofid(fp, F_STARTOB);
@ -14569,7 +14593,9 @@ int lockpick(lifeform_t *lf, cell_t *targcell, object_t *target, object_t *devic
void loseobflags(lifeform_t *lf, object_t *o, int kind) { void loseobflags(lifeform_t *lf, object_t *o, int kind) {
flag_t *f,*ff,*nextff; flag_t *f,*ff,*nextff;
for (f = o->flags->first ; f ; f = f->next) { int b;
foreach_bucket(b) {
for (f = o->flags->first[b] ; f ; f = f->next) {
int checkthis = B_FALSE; int checkthis = B_FALSE;
if (kind == ALLCONFERRED) { if (kind == ALLCONFERRED) {
if ((f->id == F_EQUIPCONFER) || (f->id == F_HOLDCONFER) || (f->id == F_ACTIVATECONFER)) { if ((f->id == F_EQUIPCONFER) || (f->id == F_HOLDCONFER) || (f->id == F_ACTIVATECONFER)) {
@ -14581,7 +14607,7 @@ void loseobflags(lifeform_t *lf, object_t *o, int kind) {
} }
} }
if (checkthis) { if (checkthis) {
int lifetimecheck; int lifetimecheck,b2;
// probably don't need this now that we are using // probably don't need this now that we are using
// flag->obfrom... // flag->obfrom...
if (f->id == F_EQUIPCONFER) { if (f->id == F_EQUIPCONFER) {
@ -14594,7 +14620,8 @@ void loseobflags(lifeform_t *lf, object_t *o, int kind) {
// not using killflagsofid() because we only want // not using killflagsofid() because we only want
// to kill flags which came from this object // to kill flags which came from this object
for (ff = lf->flags->first ; ff ; ff = nextff) { foreach_bucket(b2) {
for (ff = lf->flags->first[b2] ; ff ; ff = nextff) {
nextff = ff->next; nextff = ff->next;
if ( (ff->id == f->val[0]) && if ( (ff->id == f->val[0]) &&
(ff->val[0] == f->val[1]) && (ff->val[0] == f->val[1]) &&
@ -14607,6 +14634,8 @@ void loseobflags(lifeform_t *lf, object_t *o, int kind) {
} }
} }
} }
}
}
} }
int handlearmour(lifeform_t *lf, object_t *fromob, int *dam, enum DAMTYPE dt) { int handlearmour(lifeform_t *lf, object_t *fromob, int *dam, enum DAMTYPE dt) {
@ -16248,7 +16277,7 @@ object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int dos
object_t *footprint, *scent,*retob = NULL; object_t *footprint, *scent,*retob = NULL;
flag_t *fpflag = NULL; flag_t *fpflag = NULL;
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
// no tracks at all? // no tracks at all?
if (where->type->solid) { if (where->type->solid) {
@ -16275,7 +16304,7 @@ object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int dos
fpdir = dir; fpdir = dir;
} }
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
footprint = hastrailof(where->obpile, lf, OT_FOOTPRINT, &fpflag, NULL); footprint = hastrailof(where->obpile, lf, OT_FOOTPRINT, &fpflag, NULL);
if (footprint) { if (footprint) {
@ -16286,14 +16315,14 @@ object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int dos
char buf[BUFLENTINY]; char buf[BUFLENTINY];
snprintf(buf, BUFLENTINY, "%d", lf->id); snprintf(buf, BUFLENTINY, "%d", lf->id);
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
footprint = addobfast(where->obpile, OT_FOOTPRINT); footprint = addobfast(where->obpile, OT_FOOTPRINT);
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
addtempflag(footprint->flags, F_TRAIL, lf->race->id, fpdir, S_SIGHT, buf, getfootprinttime(lf)); addtempflag(footprint->flags, F_TRAIL, lf->race->id, fpdir, S_SIGHT, buf, getfootprinttime(lf));
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
} }
retob = footprint; retob = footprint;
@ -16310,19 +16339,19 @@ object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int dos
char buf[BUFLENTINY]; char buf[BUFLENTINY];
snprintf(buf, BUFLENTINY, "%d", lf->id); snprintf(buf, BUFLENTINY, "%d", lf->id);
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
scent = addobfast(where->obpile, OT_SCENT); scent = addobfast(where->obpile, OT_SCENT);
assert(scent); assert(scent);
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
addtempflag(scent->flags, F_TRAIL, lf->race->id, dir, S_SMELL, buf, TM_SCENT); addtempflag(scent->flags, F_TRAIL, lf->race->id, dir, S_SMELL, buf, TM_SCENT);
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
} }
retob = scent; retob = scent;
} }
checkflagpile_maplfs(lf->cell->map); //checkflagpile_maplfs(lf->cell->map);
return retob; return retob;
} }
@ -18400,7 +18429,7 @@ void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fr
void loselevel(lifeform_t *lf, int amt, lifeform_t *fromlf) { void loselevel(lifeform_t *lf, int amt, lifeform_t *fromlf) {
flag_t *f,*nextf; flag_t *f,*nextf;
float hpratio,mpratio; float hpratio,mpratio;
int newlev; int newlev,b;
int ndice,nsides,plus; int ndice,nsides,plus;
int nretflags,i; int nretflags,i;
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
@ -18461,12 +18490,14 @@ void loselevel(lifeform_t *lf, int amt, lifeform_t *fromlf) {
} }
// lose flags. // lose flags.
for (f = lf->flags->first ; f; f = nextf) { foreach_bucket(b) {
for (f = lf->flags->first[b] ; f; f = nextf) {
nextf = f->next; nextf = f->next;
if (f->fromlev > newlev) { if (f->fromlev > newlev) {
killflag(f); killflag(f);
} }
} }
}
if (isplayer(lf)) { if (isplayer(lf)) {
statdirty = B_TRUE; statdirty = B_TRUE;
@ -21967,7 +21998,7 @@ void setkillverb(lifeform_t *lf, char *buf) {
void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) { void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
flag_t *f,*nextf; flag_t *f,*nextf;
int i,retainhp = B_FALSE; int i,b,retainhp = B_FALSE;
int nkilled = 0; int nkilled = 0;
race_t *newrace; race_t *newrace;
char buf[BUFLEN]; char buf[BUFLEN];
@ -22093,7 +22124,8 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
// first remove flags from existing race, or temporary ones // first remove flags from existing race, or temporary ones
lf->born = B_FALSE; lf->born = B_FALSE;
for (f = lf->flags->first ; f ; f = nextf) { foreach_bucket(b) {
for (f = lf->flags->first[b] ; f ; f = nextf) {
nextf = f->next; nextf = f->next;
if (frompolymorph && flagretainedduringpoly(f->id)) continue; if (frompolymorph && flagretainedduringpoly(f->id)) continue;
if (lycanthrope) { if (lycanthrope) {
@ -22126,6 +22158,7 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
} }
} }
} }
}
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
// set race // set race
@ -22135,7 +22168,8 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
lf->material = lf->race->material; lf->material = lf->race->material;
// inherit most flags from new race // inherit most flags from new race
for (f = lf->race->flags->first ; f ; f = f->next) { foreach_bucket(b) {
for (f = lf->race->flags->first[b] ; f ; f = f->next) {
int ignorethis = B_FALSE; int ignorethis = B_FALSE;
switch (f->id) { switch (f->id) {
case F_RARITY: case F_RARITY:
@ -22160,6 +22194,7 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
break; break;
} }
} }
}
/* /*
copyflags(lf->flags, lf->race->flags, FROMRACE); copyflags(lf->flags, lf->race->flags, FROMRACE);
@ -25711,7 +25746,7 @@ int throwat(lifeform_t *thrower, object_t *o, cell_t *where) {
void timeeffectslf(lifeform_t *lf) { void timeeffectslf(lifeform_t *lf) {
object_t *o, *nexto; object_t *o, *nexto;
flag_t *f,*nextf; flag_t *f,*nextf;
int dir; int dir,b;
// make SURE we don't take any time! // make SURE we don't take any time!
notime = B_MAYBE; notime = B_MAYBE;
@ -25720,7 +25755,8 @@ void timeeffectslf(lifeform_t *lf) {
timeeffectsflags(lf->flags); timeeffectsflags(lf->flags);
// remove effects from expired poison // remove effects from expired poison
for (f = lf->flags->first ; f; f = nextf) { foreach_bucket(b) {
for (f = lf->flags->first[b] ; f; f = nextf) {
nextf = f->next; nextf = f->next;
if (f->lifetime == FROMPOISON) { if (f->lifetime == FROMPOISON) {
if (!lfhasflagval(lf, F_POISONED, f->obfrom, NA, NA, NULL)) { if (!lfhasflagval(lf, F_POISONED, f->obfrom, NA, NA, NULL)) {
@ -25728,6 +25764,7 @@ void timeeffectslf(lifeform_t *lf) {
} }
} }
} }
}
if (lfhasflag(lf, F_INTERRUPTED)) { if (lfhasflag(lf, F_INTERRUPTED)) {
interrupt(lf); interrupt(lf);
@ -26908,7 +26945,7 @@ int validateraces(void) {
flag_t *f; flag_t *f;
skill_t *sk; skill_t *sk;
job_t *j; job_t *j;
int i; int i,b;
cell_t fakecell; cell_t fakecell;
map_t fakemap; map_t fakemap;
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
@ -26981,7 +27018,8 @@ int validateraces(void) {
goterror = B_TRUE; goterror = B_TRUE;
} }
for (f = r->flags->first ; f ; f = f->next) { foreach_bucket(b) {
for (f = r->flags->first[b] ; f ; f = f->next) {
if (f->id == F_RNDSPELLCOUNT) { if (f->id == F_RNDSPELLCOUNT) {
if (!hasflag(r->flags, F_RNDSPELLSCHOOL) && !hasflag(r->flags, F_RNDSPELLPOSS)) { if (!hasflag(r->flags, F_RNDSPELLSCHOOL) && !hasflag(r->flags, F_RNDSPELLPOSS)) {
printf("ERROR in race '%s' - F_RNDSPELLCOUNT but no spell candidates.\n", r->name); printf("ERROR in race '%s' - F_RNDSPELLCOUNT but no spell candidates.\n", r->name);
@ -27073,6 +27111,7 @@ int validateraces(void) {
goterror = B_TRUE; goterror = B_TRUE;
} }
} }
}
} // end foreach flag } // end foreach flag

11
map.c
View File

@ -137,10 +137,12 @@ habitat_t *addhabitat(enum HABITAT id, char *name, enum CELLTYPE emptycell, enum
} }
void addhomeobs(lifeform_t *lf, int dolevelobs) { void addhomeobs(lifeform_t *lf, int dolevelobs) {
int b;
flag_t *f; flag_t *f;
cell_t *homeobloc; cell_t *homeobloc;
homeobloc = lf->cell; homeobloc = lf->cell;
for (f = lf->flags->first ; f ; f = f->next) { foreach_bucket(b) {
for (f = lf->flags->first[b] ; f ; f = f->next) {
if ((f->id == F_HOMEOB) && pctchance(f->val[0])) { if ((f->id == F_HOMEOB) && pctchance(f->val[0])) {
object_t *o = NULL; object_t *o = NULL;
cell_t *c; cell_t *c;
@ -204,6 +206,7 @@ void addhomeobs(lifeform_t *lf, int dolevelobs) {
} }
} }
} }
}
} }
map_t *addmap(void) { map_t *addmap(void) {
@ -8674,7 +8677,7 @@ void initmap(void) {
void initmaplayout(void) { void initmaplayout(void) {
//int vx[4],vy[4]; //int vx[4],vy[4];
int i; int i,b;
int lastlevel; int lastlevel;
branch_t *rt; branch_t *rt;
race_t *r; race_t *r;
@ -8782,7 +8785,8 @@ void initmaplayout(void) {
addregion(BH_HEAVEN, NULL, -1, 0, -1); addregion(BH_HEAVEN, NULL, -1, 0, -1);
// add remembered unique lfs // add remembered unique lfs
for (f = uniquelfs->first ; f ; f = f->next) { foreach_bucket(b) {
for (f = uniquelfs->first[b] ; f ; f = f->next) {
regionoutline_t *ro; regionoutline_t *ro;
ro = findoutlineforbranch(f->val[1]); ro = findoutlineforbranch(f->val[1]);
if (ro) { if (ro) {
@ -8796,6 +8800,7 @@ void initmaplayout(void) {
} }
} }
}
killflagpile(uniquelfs); killflagpile(uniquelfs);
} }

14
nexus.c
View File

@ -1034,7 +1034,7 @@ void donextturn(map_t *map) {
if (who) { if (who) {
if (db) dblog("**** donextturn for: id %d %s", who->id, who->race->name); if (db) dblog("**** donextturn for: id %d %s", who->id, who->race->name);
checkflagpile(who->flags); //checkflagpile(who->flags);
if (who->timespent > 0) { if (who->timespent > 0) {
// shuffling lf times... // shuffling lf times...
@ -1420,11 +1420,11 @@ void donextturn(map_t *map) {
if (getoption(OPT_TIMEDEBUG)) { if (getoption(OPT_TIMEDEBUG)) {
dbtimeendlf(who); dbtimeendlf(who);
} }
checkflagpile(who->flags); //checkflagpile(who->flags);
} // end 'if (who)' } // end 'if (who)'
for (l = map->lf ; l ; l = l->next) { for (l = map->lf ; l ; l = l->next) {
checkflagpile(l->flags); //checkflagpile(l->flags);
} }
if (isplayer(who)) { if (isplayer(who)) {
@ -2257,7 +2257,7 @@ void timeeffectsworld(map_t *map, int updategametime) {
/* /*
for (l = map->lf ; l ; l = nextl) { for (l = map->lf ; l ; l = nextl) {
nextl = l->next; nextl = l->next;
checkflagpile(l->flags); //checkflagpile(l->flags);
} }
*/ */
@ -2326,7 +2326,7 @@ void timeeffectsworld(map_t *map, int updategametime) {
nexto = o->next; nexto = o->next;
assert(nexto != o); assert(nexto != o);
checkflagpile(o->flags); //checkflagpile(o->flags);
timeeffectsob(o); timeeffectsob(o);
} // end foreach object here } // end foreach object here
@ -2371,9 +2371,9 @@ void timeeffectsworld(map_t *map, int updategametime) {
// now handle effects on lifeforms and/or their objects // now handle effects on lifeforms and/or their objects
for (l = map->lf ; l ; l = nextl) { for (l = map->lf ; l ; l = nextl) {
nextl = l->next; nextl = l->next;
checkflagpile(l->flags); //checkflagpile(l->flags);
timeeffectslf(l); timeeffectslf(l);
checkflagpile(l->flags); //checkflagpile(l->flags);
} }
// time out warnings // time out warnings

View File

@ -3377,6 +3377,7 @@ object_t *canstacknewot(obpile_t *op, objecttype_t *match) {
int changemat(object_t *o, enum MATERIAL mat) { int changemat(object_t *o, enum MATERIAL mat) {
material_t *m; material_t *m;
flag_t *f, *nextf; flag_t *f, *nextf;
int b;
m = findmaterial(mat); m = findmaterial(mat);
if (!m) { if (!m) {
@ -3399,12 +3400,14 @@ int changemat(object_t *o, enum MATERIAL mat) {
} }
// remove flags which came from old material // remove flags which came from old material
for (f = o->flags->first ; f; f = nextf) { foreach_bucket(b) {
for (f = o->flags->first[b] ; f; f = nextf) {
nextf = f->next; nextf = f->next;
if (f->lifetime == FROMMAT) { if (f->lifetime == FROMMAT) {
killflag(f); killflag(f);
} }
} }
}
// change material // change material
o->material = m; o->material = m;
@ -3530,6 +3533,7 @@ int confirmknowntraps(object_t *o) {
} }
void copyobprops(object_t *dst, object_t *src) { void copyobprops(object_t *dst, object_t *src) {
int b;
dst->material = src->material; dst->material = src->material;
dst->mass = src->mass; dst->mass = src->mass;
if (src->inscription) { if (src->inscription) {
@ -3538,10 +3542,13 @@ void copyobprops(object_t *dst, object_t *src) {
setblessed(dst, src->blessed); setblessed(dst, src->blessed);
dst->blessknown = src->blessknown; dst->blessknown = src->blessknown;
// copy flags // kill existing flags
while (dst->flags->first) { foreach_bucket(b) {
killflag(dst->flags->first); while (dst->flags->first[b]) {
killflag(dst->flags->first[b]);
} }
}
// copy flags
copyflags(dst->flags, src->flags, NA); copyflags(dst->flags, src->flags, NA);
} }
@ -6170,7 +6177,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
cell_t *where; cell_t *where;
int no_a = B_FALSE; int no_a = B_FALSE;
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags = 0,i; int nretflags = 0,i,b;
// default to normal name // default to normal name
/* /*
@ -6725,7 +6732,8 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
f = retflag[i]; f = retflag[i];
br = findbrand(f->val[0]); br = findbrand(f->val[0]);
// are all of the brand flags known? // are all of the brand flags known?
for (brf = br->flags->first ; brf ; brf = brf->next) { foreach_bucket(b) {
for (brf = br->flags->first[b] ; brf ; brf = brf->next) {
flag_t *retflag2[MAXCANDIDATES],*f2; flag_t *retflag2[MAXCANDIDATES],*f2;
int nretflags2 = 0,n; int nretflags2 = 0,n;
getflags(o->flags, retflag2, &nretflags2, brf->id, F_NONE); getflags(o->flags, retflag2, &nretflags2, brf->id, F_NONE);
@ -6741,6 +6749,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
} }
} }
} }
}
if (ok) { if (ok) {
strcat(localbuf, br->suffix); strcat(localbuf, br->suffix);
} }
@ -7871,8 +7880,9 @@ object_t *hasobofmaterial(obpile_t *op, enum MATERIAL mid) {
int hasobmod(object_t *o, obmod_t *om) { int hasobmod(object_t *o, obmod_t *om) {
flag_t *omf; flag_t *omf;
int found = B_TRUE; int found = B_TRUE,b;
for (omf = om->flags->first ; omf ; omf = omf->next){ foreach_bucket(b) {
for (omf = om->flags->first[b] ; omf ; omf = omf->next){
int val[3],i; int val[3],i;
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
if (omf->obmodignoreval[i]) val[i] = NA; if (omf->obmodignoreval[i]) val[i] = NA;
@ -7883,6 +7893,7 @@ int hasobmod(object_t *o, obmod_t *om) {
break; break;
} }
} }
}
return found; return found;
} }
@ -7957,15 +7968,18 @@ object_t *hassecretdoor(obpile_t *op) {
// fully identify a single object. // fully identify a single object.
void identify(object_t *o) { void identify(object_t *o) {
int b;
flag_t *f; flag_t *f;
if (!isknown(o) && (o->type->obclass->id != OC_BOOK)) { if (!isknown(o) && (o->type->obclass->id != OC_BOOK)) {
makeknown(o->type->id); makeknown(o->type->id);
} }
addflag(o->flags, F_IDENTIFIED, B_TRUE, -1, -1, NULL); addflag(o->flags, F_IDENTIFIED, B_TRUE, -1, -1, NULL);
o->blessknown = B_TRUE; o->blessknown = B_TRUE;
for (f = o->flags->first ; f ; f = f->next) { foreach_bucket(b) {
for (f = o->flags->first[b] ; f ; f = f->next) {
if (!f->known) f->known = B_TRUE; if (!f->known) f->known = B_TRUE;
} }
}
} }
void ignite(object_t *o) { void ignite(object_t *o) {
@ -8366,15 +8380,18 @@ int isheavyweapon(object_t *o) {
// AND // AND
// you know whether it is cursed or not // you know whether it is cursed or not
int isidentified(object_t *o) { int isidentified(object_t *o) {
int b;
flag_t *f; flag_t *f;
// blessed status not known? // blessed status not known?
if (!isblessknown(o)) return B_FALSE; if (!isblessknown(o)) return B_FALSE;
// unknown object type? // unknown object type?
if (!isknown(o)) return B_FALSE; if (!isknown(o)) return B_FALSE;
// unknown flags? // unknown flags?
for (f = o->flags->first ; f ; f = f->next) { foreach_bucket(b) {
for (f = o->flags->first[b] ; f ; f = f->next) {
if (!f->known) return B_FALSE; if (!f->known) return B_FALSE;
} }
}
return B_TRUE; return B_TRUE;
} }
@ -12594,7 +12611,7 @@ int pour(lifeform_t *lf, object_t *o) {
int playercansee; int playercansee;
char ch; char ch;
object_t *dst = NULL; object_t *dst = NULL;
int doneask = B_FALSE; int doneask = B_FALSE,b;
getobname(o, obname, 1); getobname(o, obname, 1);
getlfname(lf, lfname); getlfname(lf, lfname);
@ -12748,7 +12765,8 @@ int pour(lifeform_t *lf, object_t *o) {
// remove bonuses // remove bonuses
killflagsofid(dst->flags, F_BONUS); killflagsofid(dst->flags, F_BONUS);
// remove temporary flags, obmod flags and modify some others // remove temporary flags, obmod flags and modify some others
for (f = dst->flags->first ; f ; f = nextf) { foreach_bucket(b) {
for (f = dst->flags->first[b] ; f ; f = nextf) {
nextf = f->next; nextf = f->next;
if (f->lifetime > 0) { if (f->lifetime > 0) {
killflag(f); killflag(f);
@ -12765,6 +12783,7 @@ int pour(lifeform_t *lf, object_t *o) {
} }
} }
} }
}
// we now know what the potion was // we now know what the potion was
if (!isknown(o)) makeknown(o->type->id); if (!isknown(o)) makeknown(o->type->id);
@ -13531,7 +13550,7 @@ int readsomething(lifeform_t *lf, object_t *o) {
int willid = B_FALSE; int willid = B_FALSE;
int needsob = B_FALSE; int needsob = B_FALSE;
objecttype_t *linkspell; objecttype_t *linkspell;
int readtime; int readtime,b;
int pleasemagicgod = B_FALSE; int pleasemagicgod = B_FALSE;
if (!haslos(lf, lf->cell)) { if (!haslos(lf, lf->cell)) {
@ -13965,12 +13984,14 @@ int readsomething(lifeform_t *lf, object_t *o) {
enum ATTRIB a; enum ATTRIB a;
flag_t *f; flag_t *f;
// makes certain flags permenant // makes certain flags permenant
for (f = lf->flags->first ; f ; f = f->next) { foreach_bucket(b) {
for (f = lf->flags->first[b] ; f ; f = f->next) {
if ((f->lifetime > 0) && canbemadepermenant(f->id)) { if ((f->lifetime > 0) && canbemadepermenant(f->id)) {
f->lifetime = PERMENANT; f->lifetime = PERMENANT;
ndone++; ndone++;
} }
} }
}
// make enhanced/reduced attributes permenant // make enhanced/reduced attributes permenant
for (a = 0; a < MAXATTS; a++) { for (a = 0; a < MAXATTS; a++) {
int innate,actual; int innate,actual;
@ -14341,7 +14362,7 @@ int removedeadobs(obpile_t *op) {
for (o = op->first ; o ; o = nexto) { for (o = op->first ; o ; o = nexto) {
nexto = o->next; nexto = o->next;
if (hasflag(o->flags, F_DEAD)) { if (hasflag(o->flags, F_DEAD)) {
checkflagpile(o->flags); //checkflagpile(o->flags);
obdie(o); obdie(o);
nremoved++; nremoved++;
} }
@ -14437,17 +14458,20 @@ void rrtorarity(enum RARITY r, int *minr, int *maxr) {
} }
void setblessed(object_t *o, enum BLESSTYPE wantbless) { void setblessed(object_t *o, enum BLESSTYPE wantbless) {
int b;
o->blessed = wantbless; o->blessed = wantbless;
if (wantbless != B_BLESSED) { if (wantbless != B_BLESSED) {
flag_t *f,*nextf; flag_t *f,*nextf;
// remove glowing from blessings // remove glowing from blessings
for (f = o->flags->first ; f ; f = nextf) { foreach_bucket(b) {
for (f = o->flags->first[b] ; f ; f = nextf) {
nextf = f->next; nextf = f->next;
if (f->lifetime == FROMBLESSING) { if (f->lifetime == FROMBLESSING) {
killflag(f); killflag(f);
} }
} }
} }
}
} }
// returns TRUE if we set something // returns TRUE if we set something
@ -16269,7 +16293,7 @@ void timeeffectsob(object_t *o) {
strcpy(obname, "?some_ob?"); strcpy(obname, "?some_ob?");
} }
checkflagpile(o->flags); //checkflagpile(o->flags);
// special case for trail flags // special case for trail flags
f = hasflag(o->flags, F_TRAIL); f = hasflag(o->flags, F_TRAIL);
@ -16362,7 +16386,7 @@ void timeeffectsob(object_t *o) {
// expire flags // expire flags
timeeffectsflags(o->flags); timeeffectsflags(o->flags);
checkflagpile(o->flags); //checkflagpile(o->flags);
// blessed weapons glow when held near undead // blessed weapons glow when held near undead
if (isblessed(o) && isweapon(o)) { if (isblessed(o) && isweapon(o)) {
@ -17241,7 +17265,7 @@ void timeeffectsob(object_t *o) {
} }
} }
checkflagpile(o->flags); //checkflagpile(o->flags);
} }
int touch_battle_spoils(object_t *o) { int touch_battle_spoils(object_t *o) {

21
save.c
View File

@ -155,7 +155,7 @@ lifeform_t *loadlf(FILE *f, cell_t *where) {
int lfid, lfraceid; int lfid, lfraceid;
long obid; long obid;
int rv; int rv;
int i; int i,b;
char buf[BUFLEN]; char buf[BUFLEN];
int obcount; int obcount;
int mapid; int mapid;
@ -228,8 +228,10 @@ lifeform_t *loadlf(FILE *f, cell_t *where) {
if (db) dblog("--> Got hp=%d/%d. timespend=%d. sorted=%d. Now loading flags.",l->hp,l->maxhp,l->timespent,l->sorted); if (db) dblog("--> Got hp=%d/%d. timespend=%d. sorted=%d. Now loading flags.",l->hp,l->maxhp,l->timespent,l->sorted);
// clear existing flags from addlf // clear existing flags from addlf
while (l->flags->first) { foreach_bucket(b) {
killflag(l->flags->first); while (l->flags->first[b]) {
killflag(l->flags->first[b]);
}
} }
// load lf flags // load lf flags
loadflagpile(f, l->flags); loadflagpile(f, l->flags);
@ -542,7 +544,7 @@ int loadob(FILE *f, obpile_t *op, long *id) {
object_t *o; object_t *o;
material_t *mat; material_t *mat;
long obid; long obid;
int otid,matid; int otid,matid,b;
char buf[BUFLEN]; char buf[BUFLEN];
int db = B_TRUE; int db = B_TRUE;
@ -591,8 +593,10 @@ int loadob(FILE *f, obpile_t *op, long *id) {
// from the obtype during addobject() ). these will be // from the obtype during addobject() ). these will be
// loaded in instead. // loaded in instead.
while (o->flags->first) { foreach_bucket(b) {
killflag(o->flags->first); while (o->flags->first[b]) {
killflag(o->flags->first[b]);
}
} }
dblog("About to start loading object flags..."); dblog("About to start loading object flags...");
@ -926,9 +930,11 @@ int savebones(map_t *m, room_t *r) {
} }
int saveflagpile(FILE *f, flagpile_t *fp) { int saveflagpile(FILE *f, flagpile_t *fp) {
int b;
flag_t *fl; flag_t *fl;
fprintf(f, "flags:\n"); fprintf(f, "flags:\n");
for (fl = fp->first ; fl ; fl = fl->next) { foreach_bucket(b) {
for (fl = fp->first[b] ; fl ; fl = fl->next) {
assert(!fl->skillfrom || findskill(fl->skillfrom->id)); assert(!fl->skillfrom || findskill(fl->skillfrom->id));
@ -940,6 +946,7 @@ int saveflagpile(FILE *f, flagpile_t *fp) {
fprintf(f, "%s\n",fl->text); fprintf(f, "%s\n",fl->text);
} }
} }
}
fprintf(f, "-1,-1,-1,-1,-1,-1,-1,-1\n"); fprintf(f, "-1,-1,-1,-1,-1,-1,-1,-1\n");
return B_FALSE; return B_FALSE;
} }

45
spell.c
View File

@ -4153,7 +4153,7 @@ int checkcharm(lifeform_t *caster, lifeform_t *target) {
int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_t *target, object_t *targob, cell_t *targcell, int blessed, int *seenbyplayer, int frompot, object_t *fromob) { int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_t *target, object_t *targob, cell_t *targcell, int blessed, int *seenbyplayer, int frompot, object_t *fromob) {
char buf[BUFLEN]; char buf[BUFLEN];
char castername[BUFLEN]; char castername[BUFLEN];
int rv = B_FALSE; int rv = B_FALSE,b;
objecttype_t *sp; objecttype_t *sp;
flag_t *casttype = NULL; flag_t *casttype = NULL;
@ -6766,7 +6766,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
npoisoned++; npoisoned++;
killflagsofid(o->flags, F_SECRET); killflagsofid(o->flags, F_SECRET);
} else { } else {
for (f = o->flags->first ; f ; f = f->next) { foreach_bucket(b) {
for (f = o->flags->first[b] ; f ; f = f->next) {
if (f->id == F_POISONED) { if (f->id == F_POISONED) {
ispoisoned = B_TRUE; ispoisoned = B_TRUE;
f->known = B_TRUE; f->known = B_TRUE;
@ -6777,6 +6778,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
break; break;
} }
} }
}
f = hasflag(o->flags, F_TRAPPED); f = hasflag(o->flags, F_TRAPPED);
if (f) { if (f) {
if ((f->val[0] == OT_TRAPARROWP) || if ((f->val[0] == OT_TRAPARROWP) ||
@ -7223,7 +7225,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
flag_t *f; flag_t *f;
// already feebleminded? // already feebleminded?
for (f = target->flags->first; f ; f = f->next) { foreach_bucket(b) {
for (f = target->flags->first[b]; f ; f = f->next) {
if ((f->id == F_ATTRMOD) && (f->val[0] == A_IQ) && (f->obfrom == OT_S_FEEBLEMIND)) { if ((f->id == F_ATTRMOD) && (f->val[0] == A_IQ) && (f->obfrom == OT_S_FEEBLEMIND)) {
if (cansee(player, target)) { if (cansee(player, target)) {
getlfname(target, buf); getlfname(target, buf);
@ -7233,6 +7236,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
return B_FALSE; return B_FALSE;
} }
} }
}
howlong = getspellduration(5,10,blessed) + power; howlong = getspellduration(5,10,blessed) + power;
// always set to 3 (ie. animal) // always set to 3 (ie. animal)
@ -11532,7 +11536,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
return B_TRUE; return B_TRUE;
} }
for (f = target->flags->first ; f ; f = f->next) { foreach_bucket(b) {
for (f = target->flags->first[b] ; f ; f = f->next) {
if (f->id == F_POISONED) { if (f->id == F_POISONED) {
poisontype_t *pt; poisontype_t *pt;
pt = findpoisontype(f->val[0]); pt = findpoisontype(f->val[0]);
@ -11552,6 +11557,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
f->val[1] *= 2; // take longer to incubate f->val[1] *= 2; // take longer to incubate
} }
} }
}
if (ndone) { if (ndone) {
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} else { } else {
@ -11829,7 +11835,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// remove invisibility/hiding // remove invisibility/hiding
if (targcell->lf) { if (targcell->lf) {
flag_t *f, *nextf; flag_t *f, *nextf;
for (f = targcell->lf->flags->first ; f ; f = nextf) { foreach_bucket(b) {
for (f = targcell->lf->flags->first[b] ; f ; f = nextf) {
nextf = f->next; nextf = f->next;
if (f->id == F_INVISIBLE) { if (f->id == F_INVISIBLE) {
if ((f->lifetime > 0) || (f->lifetime == PERMENANT)) { if ((f->lifetime > 0) || (f->lifetime == PERMENANT)) {
@ -11857,6 +11864,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
} }
} }
}
if (seen) { if (seen) {
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
@ -13934,7 +13942,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
flag_t *f; flag_t *f;
// already weakaned? // already weakaned?
for (f = target->flags->first; f ; f = f->next) { foreach_bucket(b) {
for (f = target->flags->first[b]; f ; f = f->next) {
if ((f->id == F_ATTRMOD) && (f->val[0] == A_STR) && (f->obfrom == OT_S_WEAKEN)) { if ((f->id == F_ATTRMOD) && (f->val[0] == A_STR) && (f->obfrom == OT_S_WEAKEN)) {
if (cansee(player, target)) { if (cansee(player, target)) {
getlfname(target, buf); getlfname(target, buf);
@ -13944,6 +13953,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
return B_FALSE; return B_FALSE;
} }
} }
}
howlong = getspellduration(5,10,blessed) + power; howlong = getspellduration(5,10,blessed) + power;
f = addtempflag(target->flags, F_ATTRMOD, A_STR, power*-15, NA, NULL, howlong); f = addtempflag(target->flags, F_ATTRMOD, A_STR, power*-15, NA, NULL, howlong);
@ -15133,7 +15143,7 @@ enum SPELLSCHOOL getspellschoolknown(lifeform_t *lf, enum OBTYPE spellid) {
enum SPELLSCHOOL thisschool; enum SPELLSCHOOL thisschool;
objecttype_t *ot; objecttype_t *ot;
enum SPELLSCHOOL poss[MAXCANDIDATES]; enum SPELLSCHOOL poss[MAXCANDIDATES];
int nposs = 0; int nposs = 0,b;
ot = findot(spellid); ot = findot(spellid);
if (!ot) { if (!ot) {
@ -15146,11 +15156,13 @@ enum SPELLSCHOOL getspellschoolknown(lifeform_t *lf, enum OBTYPE spellid) {
// make a list of all schools which this spell belongs to, and which we know. // make a list of all schools which this spell belongs to, and which we know.
thisschool = SS_NONE; thisschool = SS_NONE;
for (f = ot->flags->first ; f ; f = f->next) { foreach_bucket(b) {
for (f = ot->flags->first[b] ; f ; f = f->next) {
if ((f->id == F_SPELLSCHOOL) && getskill(lf, getschoolskill(f->val[0]))) { if ((f->id == F_SPELLSCHOOL) && getskill(lf, getschoolskill(f->val[0]))) {
poss[nposs++] = f->val[0]; poss[nposs++] = f->val[0];
} }
} }
}
if (nposs) { if (nposs) {
int i; int i;
enum SPELLSCHOOL poss2[MAXCANDIDATES]; enum SPELLSCHOOL poss2[MAXCANDIDATES];
@ -15489,14 +15501,16 @@ void pullobto(object_t *o, lifeform_t *lf) {
int stopallspells(lifeform_t *lf) { int stopallspells(lifeform_t *lf) {
flag_t *f,*nextf; flag_t *f,*nextf;
int nstopped = 0; int nstopped = 0,b;
for (f = lf->flags->first ; f ; f = nextf) { foreach_bucket(b) {
for (f = lf->flags->first[b] ; f ; f = nextf) {
nextf = f->next; nextf = f->next;
if (f->id == F_BOOSTSPELL) { if (f->id == F_BOOSTSPELL) {
if (!stopspell(lf, f->val[0])) nstopped++; if (!stopspell(lf, f->val[0])) nstopped++;
} }
} }
}
// also stop spelllike abilities // also stop spelllike abilities
nstopped += killflagsofid(lf->flags, F_FULLSHIELD); nstopped += killflagsofid(lf->flags, F_FULLSHIELD);
@ -15509,7 +15523,7 @@ int stopallspellsexcept(lifeform_t *lf, ...) {
va_list args; va_list args;
enum OBTYPE exception[MAXCANDIDATES]; enum OBTYPE exception[MAXCANDIDATES];
int nexceptions = 0; int nexceptions = 0;
int nstopped = 0; int nstopped = 0,b;
va_start(args, lf); va_start(args, lf);
exception[nexceptions] = va_arg(args, enum OBTYPE); exception[nexceptions] = va_arg(args, enum OBTYPE);
@ -15519,7 +15533,8 @@ int stopallspellsexcept(lifeform_t *lf, ...) {
} }
va_end(args); va_end(args);
for (f = lf->flags->first ; f ; f = nextf) { foreach_bucket(b) {
for (f = lf->flags->first[b] ; f ; f = nextf) {
nextf = f->next; nextf = f->next;
if (f->id == F_BOOSTSPELL) { if (f->id == F_BOOSTSPELL) {
int stopthis = B_TRUE; int stopthis = B_TRUE;
@ -15535,6 +15550,7 @@ int stopallspellsexcept(lifeform_t *lf, ...) {
} }
} }
} }
}
return nstopped; return nstopped;
} }
@ -15739,11 +15755,13 @@ int stopspell(lifeform_t *caster, enum OBTYPE spellid) {
flag_t *f,*nextf; flag_t *f,*nextf;
object_t *o, *nexto; object_t *o, *nexto;
objecttype_t *sp; objecttype_t *sp;
int b;
sp = findot(spellid); sp = findot(spellid);
if (!sp) return B_TRUE; if (!sp) return B_TRUE;
for (f = caster->flags->first ; f ; f = nextf) { foreach_bucket(b) {
for (f = caster->flags->first[b] ; f ; f = nextf) {
nextf = f->next; nextf = f->next;
if ((f->id == F_BOOSTSPELL) && (f->val[0] == spellid)) { if ((f->id == F_BOOSTSPELL) && (f->val[0] == spellid)) {
killflag(f); killflag(f);
@ -15751,6 +15769,7 @@ int stopspell(lifeform_t *caster, enum OBTYPE spellid) {
killflag(f); killflag(f);
} }
} }
}
if (isplayer(caster)) { if (isplayer(caster)) {
msg("Your %s spell disappates.",sp->name); msg("Your %s spell disappates.",sp->name);

11
vault.c
View File

@ -124,12 +124,13 @@ void addvaultcontents(map_t *m, vault_t *v, int minx, int miny, int maxx, int ma
flag_t *f; flag_t *f;
char buf[BUFLEN]; char buf[BUFLEN];
int db = B_FALSE; int db = B_FALSE;
int x,y; int x,y,b;
cell_t *c; cell_t *c;
if (db) dblog("addvaultcontenets started for vaulttype %s, version %d",v->id, rotation); if (db) dblog("addvaultcontenets started for vaulttype %s, version %d",v->id, rotation);
for (f = v->flags->first ; f ; f = f->next) { foreach_bucket(b) {
for (f = v->flags->first[b] ; f ; f = f->next) {
if ((f->id == F_VAULTATOB) || (f->id == F_VAULTATLF) || (f->id == F_VAULTATCELL)) { if ((f->id == F_VAULTATOB) || (f->id == F_VAULTATLF) || (f->id == F_VAULTATCELL)) {
if (rnd(1,100) <= f->val[2]) { if (rnd(1,100) <= f->val[2]) {
cell_t *c; cell_t *c;
@ -362,6 +363,7 @@ void addvaultcontents(map_t *m, vault_t *v, int minx, int miny, int maxx, int ma
if (db) dblog("placed %d\n", nplaced); if (db) dblog("placed %d\n", nplaced);
} }
} }
}
// set vault id for each cell (except for ones which were // set vault id for each cell (except for ones which were
// previously marked as reusable via RT_REUSABLE) // previously marked as reusable via RT_REUSABLE)
@ -1860,11 +1862,13 @@ int real_vaultthingok(enum VAULTTHING vt, char *what, int *hasfire) {
int vaultokformap(vault_t *v, map_t *m) { int vaultokformap(vault_t *v, map_t *m) {
flag_t *f; flag_t *f;
celltype_t *floortype; celltype_t *floortype;
int b;
// check HABITAT // check HABITAT
if (hasflag(v->flags, F_VAULTGOESIN)) { if (hasflag(v->flags, F_VAULTGOESIN)) {
int ok = B_FALSE; int ok = B_FALSE;
// check which habitats are valid // check which habitats are valid
for (f = v->flags->first ; f ; f = f->next) { foreach_bucket(b) {
for (f = v->flags->first[b] ; f ; f = f->next) {
if (f->id == F_VAULTGOESIN) { if (f->id == F_VAULTGOESIN) {
if (f->val[0] == m->habitat->id) { if (f->val[0] == m->habitat->id) {
ok = B_TRUE; ok = B_TRUE;
@ -1872,6 +1876,7 @@ int vaultokformap(vault_t *v, map_t *m) {
} }
} }
} }
}
if (!ok) return B_FALSE; if (!ok) return B_FALSE;
} }