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];
flag_t *newf;
checkflagpile(lf->flags); // debug
//checkflagpile(lf->flags); // debug
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.
// populate path and return
@ -369,12 +369,12 @@ flag_t *ai_createpathto(lifeform_t *lf, cell_t *targcell) {
cur = cur->parent;
}
checkflagpile(lf->flags); // debug
//checkflagpile(lf->flags); // debug
pathbuf = malloc(pathlen*6*sizeof(char));
strcpy(pathbuf, "");
checkflagpile(lf->flags); // debug
//checkflagpile(lf->flags); // debug
for (i = pathlen-1; i >= 0 ; i--) {
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 - pathbuf: [%s] ", lfname, pathbuf);
checkflagpile(lf->flags); // debug
//checkflagpile(lf->flags); // debug
newf = addflag(lf->flags, F_AIPATH, targcell->x, targcell->y, NA, pathbuf);
free(pathbuf);
checkflagpile(lf->flags); // debug
//checkflagpile(lf->flags); // debug
return newf;
}
@ -2362,13 +2362,13 @@ int aimovetotargetcell(lifeform_t *lf, flag_t *f) {
iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL);
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
if (lfhasflag(lf, F_DEBUG)) {
db = B_TRUE;
}
checkflagpile(lf->flags); // debug
//checkflagpile(lf->flags); // debug
x = f->val[0];
y = f->val[1];
@ -2486,8 +2486,8 @@ int aimovetotargetcell(lifeform_t *lf, flag_t *f) {
// move randomly now.
dorandommove(lf, B_NOBADMOVES, B_TRUE, B_FALSE); // this function will call rest() if we cant move
}
checkflagpile(lf->flags); // debug
checkflagpile_maplfs(lf->cell->map);
//checkflagpile(lf->flags); // debug
//checkflagpile_maplfs(lf->cell->map);
// success
return B_TRUE;
}
@ -2562,7 +2562,7 @@ void aiturn(lifeform_t *lf) {
lifeform_t *master = NULL;
enum ATTRBRACKET iqb;
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
/*
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. }");
taketime(lf, SPEED_DEAD);
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
return;
}
@ -2599,7 +2599,7 @@ void aiturn(lifeform_t *lf) {
if (!playerhasmoved) {
if (db) dblog(".oO { player hasn't had their initial turn yet, skipping turn. }");
taketime(lf, SPEED_DEAD);
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
return;
}
@ -2615,18 +2615,18 @@ void aiturn(lifeform_t *lf) {
master = findlf(lf->cell->map, f->val[0]);
}
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
ailoscheck(lf);
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
///////////////////////////////////////////////
// emergencies / fixing up
///////////////////////////////////////////////
if (ai_handle_emergencies(lf, iqb)) return;
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
ailoscheck(lf);
@ -2643,7 +2643,7 @@ void aiturn(lifeform_t *lf) {
///////////////////////////////////////////////
if (ai_healing(lf)) return;
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
ailoscheck(lf);
@ -2652,7 +2652,7 @@ void aiturn(lifeform_t *lf) {
///////////////////////////////////////////////
if (ai_inventory_mgt(lf, &icanattack)) return;
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
ailoscheck(lf);
///////////////////////////////////////////////
@ -2660,7 +2660,7 @@ void aiturn(lifeform_t *lf) {
///////////////////////////////////////////////
if (ai_attack_existing_target(lf)) return;
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
ailoscheck(lf);
///////////////////////////////////////////////
@ -2668,14 +2668,14 @@ void aiturn(lifeform_t *lf) {
///////////////////////////////////////////////
if (ai_premovement(lf)) return;
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
ailoscheck(lf);
///////////////////////////////////////////////
// movement
///////////////////////////////////////////////
if (ai_movement(lf)) return;
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
ailoscheck(lf);
///////////////////////////////////////////////
@ -2683,22 +2683,22 @@ void aiturn(lifeform_t *lf) {
// to attack, etc)
///////////////////////////////////////////////
if (ai_bored(lf, master, icanattack)) return;
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
ailoscheck(lf);
// DEFAULT - try to move in a random direction
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
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
ailoscheck(lf);
// somehow still here?
if (!lf->timespent) {
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.

6
defs.h
View File

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

111
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;
enum { NONE, FIRST, FIRST2, MIDDLE, LAST } fml = NONE;
checkflagpile(fp);
//checkflagpile(fp);
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
// 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);
updatefpindex(fp);
//updatefpindex(fp);
//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);
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
checkflagpile(fp);
//checkflagpile(fp);
return f;
}
@ -482,7 +482,7 @@ flagpile_t *addflagpile(lifeform_t *owner, object_t *ob) {
foreach_bucket(i) {
fp->first[i] = NULL;
fp->last[i] = NULL;
fp->nitems = 0;
//fp->nitems = 0;
}
fp->owner = owner;
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;
object_t *o;
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;
if (!flagcheck) return;
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 (fpisbad(fp)) {
assert("flagpile is corrupt!" == 0);
@ -569,7 +570,6 @@ void checkflagpile(flagpile_t *fp) {
}
/// TODO: remove this function
int fpisbad(flagpile_t *fp) {
flag_t *f;
int i;
@ -592,6 +592,7 @@ int fpisbad(flagpile_t *fp) {
}
return B_FALSE;
}
*/
// 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);
}
/*
flag_t *flag_bsearch(flagpile_t *fp, int id, int *iterp) {
flag_t *f,*searchfrom = NULL;
int pos;
@ -898,6 +900,7 @@ flag_t *flag_bsearch(flagpile_t *fp, int id, int *iterp) {
if (iterp) *iterp += iter;
return searchfrom;
}
*/
flag_t *flag_hsearch(flagpile_t *fp, int id, int *iterp) {
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 (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
//searchfrom = flag_bsearch(fp, id, &iter);
@ -936,21 +939,22 @@ flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown, flag_t *exception, i
f = searchfrom;
//while (f && (f->id == id)) { for binary search
while (f) {
int valid = B_FALSE;
if (f->id == id) {
int valid = B_TRUE;
valid = B_TRUE;
if (f == exception) valid = B_FALSE;
if ((lifetimeexception != NA) && (f->lifetime == lifetimeexception)) 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 == FROMSKILL) && !getskill(owner, xxx)) valid = B_FALSE;
if (valid) {
foundflag = f;
break;
} else {
f = f->next;
subiter++;
}
}
if (valid) {
foundflag = f;
break;
} else {
f = f->next;
subiter++;
}
}
@ -978,7 +982,6 @@ flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown, flag_t *exception, i
return NULL;
}
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
}
@ -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 *f,*foundflag = NULL, *searchfrom = NULL;
lifeform_t *owner;
int pos;
int l,r;
int iter = 0;
int db = B_FALSE;
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 (db) dblog("hasflag %d in flagpile with %d entries", id, fp->nitems);
// binary search for this flag id.
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++;
}
searchfrom = flag_hsearch(fp, id, &iter);
// now find a valid one
f = searchfrom;
while (f && (f->id == id)) {
while (f) {
if (f->id == id) {
if ((lifetimeexception != NA) && (f->lifetime == lifetimeexception)) {
// invalid
} else if (owner && (f->lifetime == FROMJOB) && !getjob(owner)) {
// invalid
} else if ( ((val1 == NA) || (f->val[0] == val1)) &&
@ -1065,8 +1028,8 @@ flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, ch
break;
}
}
f = f->next;
}
f = f->next;
}
if (db) dblog("finished - %s - iter=%d", foundflag ? "found it" : "NOT FOUND", iter );
@ -1244,7 +1207,7 @@ void real_killflag(flag_t *f, int wantannounce) {
}
}
}
checkflagpile(pile);
//checkflagpile(pile);
if (gamemode == GM_GAMESTARTED) {
// flags which cause a redraw
@ -1255,7 +1218,7 @@ void real_killflag(flag_t *f, int wantannounce) {
redolos = getflagpilelocation(f->pile);
}
}
checkflagpile(pile);
//checkflagpile(pile);
// notify
if (gamemode == GM_GAMESTARTED) {
@ -1322,7 +1285,7 @@ void real_killflag(flag_t *f, int wantannounce) {
}
}
}
checkflagpile(pile);
//checkflagpile(pile);
// determine bucket
hash = getflaghash(f->id);
@ -1369,10 +1332,10 @@ void real_killflag(flag_t *f, int wantannounce) {
//////////////////////////////////////////
f = NULL;
checkflagpile(pile);
//checkflagpile(pile);
// re-index the pile
updatefpindex(pile);
checkflagpile(pile);
//updatefpindex(pile);
//checkflagpile(pile);
if (gamemode == GM_GAMESTARTED) {
for (i = 0; i < ngodlfs; i++) {
@ -1843,16 +1806,16 @@ void timeeffectsflags(flagpile_t *fp) {
timeeffectsflag(f, 1);
// if this checkflag() crashes, we know there we a bug during processing of
// flag 'thisid'
checkflagpile(fp);
//checkflagpile(fp);
}
}
//checkflagpile(fp);
}
// generate an index
/*
void updatefpindex(flagpile_t *fp) {
return;
/*
flag_t *f;
fp->nitems = 0;
@ -1864,5 +1827,5 @@ void updatefpindex(flagpile_t *fp) {
fp->nitems++;
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);
int canbemadepermenant(enum FLAG id);
void changeflagtext(flag_t *f, char *newtext);
/*
int fpisbad(flagpile_t *fp);
void checkflagpile(flagpile_t *fp);
void checkflagpile_maplfs(map_t *m);
void checkflagpile_mapobs(map_t *m);
*/
int copyflag(flagpile_t *dst, flagpile_t *src, enum FLAG id);
void copyflags(flagpile_t *dst, flagpile_t *src, int lifetime);
int countflags(flagpile_t *fp);
int countflagsofid(flagpile_t *fp, enum FLAG fid );
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);
int flagcausesinterrupt(flag_t *f, enum GAINORLOSS gol);
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 timeeffectsflag(flag_t *f, int howlong);
void timeeffectsflags(flagpile_t *fp);
void updatefpindex(flagpile_t *fp);
//void updatefpindex(flagpile_t *fp);

131
lf.c
View File

@ -3328,7 +3328,7 @@ int die(lifeform_t *lf) {
int willbecomeghost = B_FALSE;
object_t *corpse = NULL;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
int nretflags,b;
cell_t *corpsecell;
lifeform_t *killer = NULL;
int dobonesfile = B_FALSE;
@ -4206,11 +4206,13 @@ int die(lifeform_t *lf) {
flag_t *f, *nextf;
// remove all job flags
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;
if (f->lifetime == FROMJOB) {
killflag(f);
}
}
}
killflagsofid(lf->flags, F_JOB);
lf->born = B_TRUE;
@ -5675,12 +5677,13 @@ void enhancerandomskill(lifeform_t *lf) {
flag_t *f;
enum SKILL poss[MAXSKILLS];
int nposs = 0;
int sel;
int sel,b;
enum SKILLLEVEL wantlev;
// enhance lower level skills first, and only up to PR_ADEPT.
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 (isplayer(lf) && (f->val[2] != B_TRUE)) {
// for player - select only from skills which we have used since last levelup.
@ -5695,6 +5698,7 @@ void enhancerandomskill(lifeform_t *lf) {
giveskill(lf, poss[sel]);
break;
}
}
}
}
@ -5708,7 +5712,7 @@ void enhanceskills(lifeform_t *lf) {
enum SKILLLEVEL slev;
int gainedxplev = B_FALSE;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
int nretflags,b;
if (lf->newlevel != lf->level) {
lf->level = lf->newlevel;
@ -5847,12 +5851,14 @@ void enhanceskills(lifeform_t *lf) {
objecttype_t *ot;
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 (lf->skillpoints >= getskilllevcost(f->val[1] + 1)) {
skillstoenhance++;
}
}
}
}
if (lf->skillpoints >= newskillcost) {
@ -6903,9 +6909,10 @@ subjob_t *findsubjobbyletter(char letter) {
// returns true if we did somethign
int fixcurses(lifeform_t *lf) {
int donesomething = B_FALSE;
int donesomething = B_FALSE,b;
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;
if (f->id == F_LYCANTHROPE) {
donesomething = B_TRUE;
@ -6924,6 +6931,7 @@ int fixcurses(lifeform_t *lf) {
killflag(f);
continue;
}
}
}
if (donesomething) {
if (isplayer(lf)) {
@ -8157,7 +8165,7 @@ int getavgdam(lifeform_t *lf, int forxp) {
int db = B_FALSE;
flag_t *f;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
int nretflags,b;
if (lfhasflag(lf, F_DEBUG)) {
db = B_TRUE;
@ -8182,7 +8190,8 @@ int getavgdam(lifeform_t *lf, int forxp) {
thisavg = ((float)min + (float)max) / 2.0;
// 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) {
flag_t *valflag;
int maxlifetime;
@ -8201,6 +8210,7 @@ int getavgdam(lifeform_t *lf, int forxp) {
break;
}
}
}
}
// modify for accuracy
@ -8233,10 +8243,12 @@ int getavgdam(lifeform_t *lf, int forxp) {
thisavg = ((float)min + (float)max) / 2.0;
// 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) {
thisavg += 10;
}
}
}
// modify for accuracy
@ -9043,7 +9055,7 @@ char *getjobname(lifeform_t *lf) {
int getjobrecommendation(race_t *r, job_t *j) {
int rec = 0;
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);
for (i = 0; i < nretflags; i++) {
@ -9078,10 +9090,12 @@ int getjobrecommendation(race_t *r, job_t *j) {
}
}
} 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])) {
rec += 1;
}
}
}
} else if ((f->id == F_DTIMMUNE) || (f->id == F_DTRESIST)) {
if (hasflag(j->flags, f->id)) {
@ -9107,10 +9121,12 @@ int getjobrecommendation(race_t *r, job_t *j) {
}
// race can't have spells, and job has a magic skill?
// (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])) {
rec -= 2;
}
}
}
// job uses mp?
if (hasflag(j->flags, F_MPDICE)) {
@ -12133,7 +12149,7 @@ void givebehaviour(lifeform_t *lf, enum BEHAVIOUR bid) {
void givejob(lifeform_t *lf, enum JOB jobid) {
job_t *j;
flag_t *f;
int i;
int i,b;
//int rollhp = B_FALSE;
int rollmp = B_FALSE;
int rollatt[MAXATTS];
@ -12194,7 +12210,8 @@ void givejob(lifeform_t *lf, enum JOB jobid) {
// - hpmod ones
// - skills which we already have f_noskill for.
// - 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;
char *text;
flag_t *f2;
@ -12256,6 +12273,7 @@ void givejob(lifeform_t *lf, enum JOB jobid) {
rollatt[val[0]] = B_TRUE;
}
}
}
}
// now give start obs/skills from the job
@ -12576,7 +12594,7 @@ void giveobflags(lifeform_t *lf, object_t *o, enum FLAG whattype) {
flag_t *f,*newflag;
int held = B_FALSE, equipped = B_FALSE,activated = B_FALSE;
int lifetimeval;
int lifetimeval,b;
if (gettechlevel(o->type->id) > getskill(lf, SK_TECHUSAGE)) {
return;
@ -12624,7 +12642,8 @@ void giveobflags(lifeform_t *lf, object_t *o, enum FLAG whattype) {
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) {
int known = B_FALSE;
int addit = B_FALSE;
@ -12669,6 +12688,7 @@ void giveobflags(lifeform_t *lf, object_t *o, enum FLAG whattype) {
flagsfound++;
}
}
}
}
// if all conferred flags now known, object is known
@ -13062,7 +13082,7 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
cell_t *mapcell;
enum LFSIZE maxobsize = SZ_MAX;
int isshop = B_FALSE;
int depthmod2 = 0;
int depthmod2 = 0,b;
cell_t fakecell;
map_t fakemap;
@ -13210,7 +13230,8 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
killfakes(&fakemap, &fakecell);
// 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 id;
char *text;
@ -13471,14 +13492,17 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
}
} else if (isshop) {
flag_t *f2;
int b2;
// all flags are known
for (f2 = o->flags->first ; f2; f2 = f2->next) {
f2->known = B_TRUE;
}
foreach_bucket(b2) {
for (f2 = o->flags->first[b2] ; f2; f2 = f2->next) {
f2->known = B_TRUE;
}
}
}
} // 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!
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) {
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;
if (kind == ALLCONFERRED) {
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) {
int lifetimecheck;
int lifetimecheck,b2;
// probably don't need this now that we are using
// flag->obfrom...
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
// 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;
if ( (ff->id == f->val[0]) &&
(ff->val[0] == f->val[1]) &&
@ -14604,8 +14631,10 @@ void loseobflags(lifeform_t *lf, object_t *o, int kind) {
killflag(ff);
}
}
}
}
}
}
}
}
@ -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;
flag_t *fpflag = NULL;
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
// no tracks at all?
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;
}
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
footprint = hastrailof(where->obpile, lf, OT_FOOTPRINT, &fpflag, NULL);
if (footprint) {
@ -16286,14 +16315,14 @@ object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int dos
char buf[BUFLENTINY];
snprintf(buf, BUFLENTINY, "%d", lf->id);
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
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));
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
}
retob = footprint;
@ -16310,19 +16339,19 @@ object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int dos
char buf[BUFLENTINY];
snprintf(buf, BUFLENTINY, "%d", lf->id);
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
scent = addobfast(where->obpile, OT_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);
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
}
retob = scent;
}
checkflagpile_maplfs(lf->cell->map);
//checkflagpile_maplfs(lf->cell->map);
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) {
flag_t *f,*nextf;
float hpratio,mpratio;
int newlev;
int newlev,b;
int ndice,nsides,plus;
int nretflags,i;
flag_t *retflag[MAXCANDIDATES];
@ -18461,11 +18490,13 @@ void loselevel(lifeform_t *lf, int amt, lifeform_t *fromlf) {
}
// 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;
if (f->fromlev > newlev) {
killflag(f);
}
}
}
if (isplayer(lf)) {
@ -21967,7 +21998,7 @@ void setkillverb(lifeform_t *lf, char *buf) {
void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
flag_t *f,*nextf;
int i,retainhp = B_FALSE;
int i,b,retainhp = B_FALSE;
int nkilled = 0;
race_t *newrace;
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
// first remove flags from existing race, or temporary ones
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;
if (frompolymorph && flagretainedduringpoly(f->id)) continue;
if (lycanthrope) {
@ -22125,6 +22157,7 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
break;
}
}
}
}
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
@ -22135,7 +22168,8 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
lf->material = lf->race->material;
// 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;
switch (f->id) {
case F_RARITY:
@ -22159,6 +22193,7 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
}
break;
}
}
}
/*
@ -25711,7 +25746,7 @@ int throwat(lifeform_t *thrower, object_t *o, cell_t *where) {
void timeeffectslf(lifeform_t *lf) {
object_t *o, *nexto;
flag_t *f,*nextf;
int dir;
int dir,b;
// make SURE we don't take any time!
notime = B_MAYBE;
@ -25720,13 +25755,15 @@ void timeeffectslf(lifeform_t *lf) {
timeeffectsflags(lf->flags);
// 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;
if (f->lifetime == FROMPOISON) {
if (!lfhasflagval(lf, F_POISONED, f->obfrom, NA, NA, NULL)) {
killflag(f);
}
}
}
}
if (lfhasflag(lf, F_INTERRUPTED)) {
@ -26908,7 +26945,7 @@ int validateraces(void) {
flag_t *f;
skill_t *sk;
job_t *j;
int i;
int i,b;
cell_t fakecell;
map_t fakemap;
flag_t *retflag[MAXCANDIDATES];
@ -26981,7 +27018,8 @@ int validateraces(void) {
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 (!hasflag(r->flags, F_RNDSPELLSCHOOL) && !hasflag(r->flags, F_RNDSPELLPOSS)) {
printf("ERROR in race '%s' - F_RNDSPELLCOUNT but no spell candidates.\n", r->name);
@ -27073,6 +27111,7 @@ int validateraces(void) {
goterror = B_TRUE;
}
}
}
} // 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) {
int b;
flag_t *f;
cell_t *homeobloc;
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])) {
object_t *o = NULL;
cell_t *c;
@ -203,6 +205,7 @@ void addhomeobs(lifeform_t *lf, int dolevelobs) {
}
}
}
}
}
}
@ -8674,7 +8677,7 @@ void initmap(void) {
void initmaplayout(void) {
//int vx[4],vy[4];
int i;
int i,b;
int lastlevel;
branch_t *rt;
race_t *r;
@ -8782,7 +8785,8 @@ void initmaplayout(void) {
addregion(BH_HEAVEN, NULL, -1, 0, -1);
// 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;
ro = findoutlineforbranch(f->val[1]);
if (ro) {
@ -8795,6 +8799,7 @@ void initmaplayout(void) {
}
}
}
}
killflagpile(uniquelfs);

14
nexus.c
View File

@ -1034,7 +1034,7 @@ void donextturn(map_t *map) {
if (who) {
if (db) dblog("**** donextturn for: id %d %s", who->id, who->race->name);
checkflagpile(who->flags);
//checkflagpile(who->flags);
if (who->timespent > 0) {
// shuffling lf times...
@ -1420,11 +1420,11 @@ void donextturn(map_t *map) {
if (getoption(OPT_TIMEDEBUG)) {
dbtimeendlf(who);
}
checkflagpile(who->flags);
//checkflagpile(who->flags);
} // end 'if (who)'
for (l = map->lf ; l ; l = l->next) {
checkflagpile(l->flags);
//checkflagpile(l->flags);
}
if (isplayer(who)) {
@ -2257,7 +2257,7 @@ void timeeffectsworld(map_t *map, int updategametime) {
/*
for (l = map->lf ; l ; l = nextl) {
nextl = l->next;
checkflagpile(l->flags);
//checkflagpile(l->flags);
}
*/
@ -2326,7 +2326,7 @@ void timeeffectsworld(map_t *map, int updategametime) {
nexto = o->next;
assert(nexto != o);
checkflagpile(o->flags);
//checkflagpile(o->flags);
timeeffectsob(o);
} // end foreach object here
@ -2371,9 +2371,9 @@ void timeeffectsworld(map_t *map, int updategametime) {
// now handle effects on lifeforms and/or their objects
for (l = map->lf ; l ; l = nextl) {
nextl = l->next;
checkflagpile(l->flags);
//checkflagpile(l->flags);
timeeffectslf(l);
checkflagpile(l->flags);
//checkflagpile(l->flags);
}
// 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) {
material_t *m;
flag_t *f, *nextf;
int b;
m = findmaterial(mat);
if (!m) {
@ -3399,11 +3400,13 @@ int changemat(object_t *o, enum MATERIAL mat) {
}
// 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;
if (f->lifetime == FROMMAT) {
killflag(f);
}
}
}
// change material
@ -3530,6 +3533,7 @@ int confirmknowntraps(object_t *o) {
}
void copyobprops(object_t *dst, object_t *src) {
int b;
dst->material = src->material;
dst->mass = src->mass;
if (src->inscription) {
@ -3538,10 +3542,13 @@ void copyobprops(object_t *dst, object_t *src) {
setblessed(dst, src->blessed);
dst->blessknown = src->blessknown;
// copy flags
while (dst->flags->first) {
killflag(dst->flags->first);
// kill existing flags
foreach_bucket(b) {
while (dst->flags->first[b]) {
killflag(dst->flags->first[b]);
}
}
// copy flags
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;
int no_a = B_FALSE;
flag_t *retflag[MAXCANDIDATES];
int nretflags = 0,i;
int nretflags = 0,i,b;
// 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];
br = findbrand(f->val[0]);
// 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;
int nretflags2 = 0,n;
getflags(o->flags, retflag2, &nretflags2, brf->id, F_NONE);
@ -6740,6 +6748,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
}
}
}
}
}
if (ok) {
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) {
flag_t *omf;
int found = B_TRUE;
for (omf = om->flags->first ; omf ; omf = omf->next){
int found = B_TRUE,b;
foreach_bucket(b) {
for (omf = om->flags->first[b] ; omf ; omf = omf->next){
int val[3],i;
for (i = 0; i < 3; i++) {
if (omf->obmodignoreval[i]) val[i] = NA;
@ -7882,6 +7892,7 @@ int hasobmod(object_t *o, obmod_t *om) {
found = B_FALSE;
break;
}
}
}
return found;
}
@ -7957,14 +7968,17 @@ object_t *hassecretdoor(obpile_t *op) {
// fully identify a single object.
void identify(object_t *o) {
int b;
flag_t *f;
if (!isknown(o) && (o->type->obclass->id != OC_BOOK)) {
makeknown(o->type->id);
}
addflag(o->flags, F_IDENTIFIED, B_TRUE, -1, -1, NULL);
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;
}
}
}
@ -8366,14 +8380,17 @@ int isheavyweapon(object_t *o) {
// AND
// you know whether it is cursed or not
int isidentified(object_t *o) {
int b;
flag_t *f;
// blessed status not known?
if (!isblessknown(o)) return B_FALSE;
// unknown object type?
if (!isknown(o)) return B_FALSE;
// 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;
}
}
return B_TRUE;
@ -12594,7 +12611,7 @@ int pour(lifeform_t *lf, object_t *o) {
int playercansee;
char ch;
object_t *dst = NULL;
int doneask = B_FALSE;
int doneask = B_FALSE,b;
getobname(o, obname, 1);
getlfname(lf, lfname);
@ -12748,7 +12765,8 @@ int pour(lifeform_t *lf, object_t *o) {
// remove bonuses
killflagsofid(dst->flags, F_BONUS);
// 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;
if (f->lifetime > 0) {
killflag(f);
@ -12763,6 +12781,7 @@ int pour(lifeform_t *lf, object_t *o) {
} else if (f->id == F_OBHP) {
f->val[0] = f->val[1];
}
}
}
}
@ -13531,7 +13550,7 @@ int readsomething(lifeform_t *lf, object_t *o) {
int willid = B_FALSE;
int needsob = B_FALSE;
objecttype_t *linkspell;
int readtime;
int readtime,b;
int pleasemagicgod = B_FALSE;
if (!haslos(lf, lf->cell)) {
@ -13965,11 +13984,13 @@ int readsomething(lifeform_t *lf, object_t *o) {
enum ATTRIB a;
flag_t *f;
// 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)) {
f->lifetime = PERMENANT;
ndone++;
}
}
}
// make enhanced/reduced attributes permenant
for (a = 0; a < MAXATTS; a++) {
@ -14341,7 +14362,7 @@ int removedeadobs(obpile_t *op) {
for (o = op->first ; o ; o = nexto) {
nexto = o->next;
if (hasflag(o->flags, F_DEAD)) {
checkflagpile(o->flags);
//checkflagpile(o->flags);
obdie(o);
nremoved++;
}
@ -14437,15 +14458,18 @@ void rrtorarity(enum RARITY r, int *minr, int *maxr) {
}
void setblessed(object_t *o, enum BLESSTYPE wantbless) {
int b;
o->blessed = wantbless;
if (wantbless != B_BLESSED) {
flag_t *f,*nextf;
// 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;
if (f->lifetime == FROMBLESSING) {
killflag(f);
}
}
}
}
}
@ -16269,7 +16293,7 @@ void timeeffectsob(object_t *o) {
strcpy(obname, "?some_ob?");
}
checkflagpile(o->flags);
//checkflagpile(o->flags);
// special case for trail flags
f = hasflag(o->flags, F_TRAIL);
@ -16362,7 +16386,7 @@ void timeeffectsob(object_t *o) {
// expire flags
timeeffectsflags(o->flags);
checkflagpile(o->flags);
//checkflagpile(o->flags);
// blessed weapons glow when held near undead
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) {

25
save.c
View File

@ -155,7 +155,7 @@ lifeform_t *loadlf(FILE *f, cell_t *where) {
int lfid, lfraceid;
long obid;
int rv;
int i;
int i,b;
char buf[BUFLEN];
int obcount;
int mapid;
@ -228,9 +228,11 @@ 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);
// clear existing flags from addlf
while (l->flags->first) {
killflag(l->flags->first);
}
foreach_bucket(b) {
while (l->flags->first[b]) {
killflag(l->flags->first[b]);
}
}
// load lf flags
loadflagpile(f, l->flags);
@ -542,7 +544,7 @@ int loadob(FILE *f, obpile_t *op, long *id) {
object_t *o;
material_t *mat;
long obid;
int otid,matid;
int otid,matid,b;
char buf[BUFLEN];
int db = B_TRUE;
@ -591,9 +593,11 @@ int loadob(FILE *f, obpile_t *op, long *id) {
// from the obtype during addobject() ). these will be
// loaded in instead.
while (o->flags->first) {
killflag(o->flags->first);
}
foreach_bucket(b) {
while (o->flags->first[b]) {
killflag(o->flags->first[b]);
}
}
dblog("About to start loading object flags...");
loadflagpile(f, o->flags);
@ -926,9 +930,11 @@ int savebones(map_t *m, room_t *r) {
}
int saveflagpile(FILE *f, flagpile_t *fp) {
int b;
flag_t *fl;
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));
@ -939,6 +945,7 @@ int saveflagpile(FILE *f, flagpile_t *fp) {
} else {
fprintf(f, "%s\n",fl->text);
}
}
}
fprintf(f, "-1,-1,-1,-1,-1,-1,-1,-1\n");
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) {
char buf[BUFLEN];
char castername[BUFLEN];
int rv = B_FALSE;
int rv = B_FALSE,b;
objecttype_t *sp;
flag_t *casttype = NULL;
@ -6766,7 +6766,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
npoisoned++;
killflagsofid(o->flags, F_SECRET);
} 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) {
ispoisoned = B_TRUE;
f->known = B_TRUE;
@ -6776,6 +6777,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
f->known = B_TRUE;
break;
}
}
}
f = hasflag(o->flags, F_TRAPPED);
if (f) {
@ -7223,7 +7225,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
flag_t *f;
// 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 (cansee(player, target)) {
getlfname(target, buf);
@ -7232,6 +7235,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
}
return B_FALSE;
}
}
}
howlong = getspellduration(5,10,blessed) + power;
@ -11532,7 +11536,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
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) {
poisontype_t *pt;
pt = findpoisontype(f->val[0]);
@ -11551,6 +11556,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else if (f->id == F_INCUBATING) {
f->val[1] *= 2; // take longer to incubate
}
}
}
if (ndone) {
if (seenbyplayer) *seenbyplayer = B_TRUE;
@ -11829,7 +11835,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// remove invisibility/hiding
if (targcell->lf) {
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;
if (f->id == F_INVISIBLE) {
if ((f->lifetime > 0) || (f->lifetime == PERMENANT)) {
@ -11853,6 +11860,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
msg("A hiding %s is revealed!", noprefix(tname));
}
}
}
}
}
}
@ -13934,7 +13942,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
flag_t *f;
// 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 (cansee(player, target)) {
getlfname(target, buf);
@ -13943,6 +13952,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
}
return B_FALSE;
}
}
}
howlong = getspellduration(5,10,blessed) + power;
@ -15133,7 +15143,7 @@ enum SPELLSCHOOL getspellschoolknown(lifeform_t *lf, enum OBTYPE spellid) {
enum SPELLSCHOOL thisschool;
objecttype_t *ot;
enum SPELLSCHOOL poss[MAXCANDIDATES];
int nposs = 0;
int nposs = 0,b;
ot = findot(spellid);
if (!ot) {
@ -15146,10 +15156,12 @@ enum SPELLSCHOOL getspellschoolknown(lifeform_t *lf, enum OBTYPE spellid) {
// make a list of all schools which this spell belongs to, and which we know.
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]))) {
poss[nposs++] = f->val[0];
}
}
}
if (nposs) {
int i;
@ -15489,13 +15501,15 @@ void pullobto(object_t *o, lifeform_t *lf) {
int stopallspells(lifeform_t *lf) {
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;
if (f->id == F_BOOSTSPELL) {
if (!stopspell(lf, f->val[0])) nstopped++;
}
}
}
// also stop spelllike abilities
@ -15509,7 +15523,7 @@ int stopallspellsexcept(lifeform_t *lf, ...) {
va_list args;
enum OBTYPE exception[MAXCANDIDATES];
int nexceptions = 0;
int nstopped = 0;
int nstopped = 0,b;
va_start(args, lf);
exception[nexceptions] = va_arg(args, enum OBTYPE);
@ -15519,7 +15533,8 @@ int stopallspellsexcept(lifeform_t *lf, ...) {
}
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;
if (f->id == F_BOOSTSPELL) {
int stopthis = B_TRUE;
@ -15534,6 +15549,7 @@ int stopallspellsexcept(lifeform_t *lf, ...) {
if (!stopspell(lf, f->val[0])) nstopped++;
}
}
}
}
return nstopped;
}
@ -15739,17 +15755,20 @@ int stopspell(lifeform_t *caster, enum OBTYPE spellid) {
flag_t *f,*nextf;
object_t *o, *nexto;
objecttype_t *sp;
int b;
sp = findot(spellid);
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;
if ((f->id == F_BOOSTSPELL) && (f->val[0] == spellid)) {
killflag(f);
} else if ((f->lifetime == FROMSPELL) && (f->obfrom == spellid)) {
killflag(f);
}
}
}
if (isplayer(caster)) {

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;
char buf[BUFLEN];
int db = B_FALSE;
int x,y;
int x,y,b;
cell_t *c;
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 (rnd(1,100) <= f->val[2]) {
cell_t *c;
@ -361,6 +362,7 @@ void addvaultcontents(map_t *m, vault_t *v, int minx, int miny, int maxx, int ma
}
if (db) dblog("placed %d\n", nplaced);
}
}
}
// set vault id for each cell (except for ones which were
@ -1860,17 +1862,20 @@ int real_vaultthingok(enum VAULTTHING vt, char *what, int *hasfire) {
int vaultokformap(vault_t *v, map_t *m) {
flag_t *f;
celltype_t *floortype;
int b;
// check HABITAT
if (hasflag(v->flags, F_VAULTGOESIN)) {
int ok = B_FALSE;
// 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->val[0] == m->habitat->id) {
ok = B_TRUE;
break;
}
}
}
}
if (!ok) return B_FALSE;
}