#include #include #include #include "defs.h" #include "flag.h" #include "io.h" #include "lf.h" #include "objects.h" #include "text.h" extern int gamestarted; flag_t *addflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text) { return addflag_real(fp, id, val1, val2, val3, text, PERMENANT, B_KNOWN); } flag_t *addtempflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text, int timeleft) { return addflag_real(fp, id, val1, val2, val3, text, timeleft, B_KNOWN); } flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text, int lifetime, int known) { flag_t *f; int i; // identified things mean all new flags are autmaticlaly known. if (hasflag(fp, F_IDENTIFIED)) { known = B_KNOWN; } // certain flags stack... if (flagstacks(id)) { f = hasflag(fp, id); if (f) { // add values! f->val[0] += val1; f->val[1] += val2; f->val[2] += val3; // TODO: how to handle text?? return f; } } if (fp->first == NULL) { fp->first = malloc(sizeof(flag_t)); f = fp->first; f->prev = NULL; } else { // go to end of list f = fp->last; f->next = malloc(sizeof(flag_t)); f->next->prev = f; f = f->next; } fp->last = f; f->next = NULL; // fill in props f->id = id; f->lifetime = lifetime; f->known = known; f->obfrom = -1; // first blank values for (i = 0; i < 3; i++) { f->val[i] = NA; } f->val[0] = val1; f->nvals = 1; if (val2 != NA) { f->val[1] = val2; f->nvals++; } if (val3 != NA) { f->val[2] = val3; f->nvals++; } if (text) { f->text = strdup(text); } else { f->text = strdup(""); } f->pile = fp; // notify if (gamestarted) { if (f->pile->owner) { if (announceflaggain(f->pile->owner, f)) { f->known = B_TRUE; } if (isplayer(f->pile->owner)) { switch (f->id) { case F_BLIND: case F_SEEINDARK: drawscreen(); break; default: break; } } } else if (f->pile->ob) { if (announceobflaggain(f->pile->ob, f)) { f->known = B_TRUE; } } } return f; } flagpile_t *addflagpile(lifeform_t *owner, object_t *ob) { flagpile_t *fp; fp = malloc(sizeof(flagpile_t)); fp->first = NULL; fp->last = NULL; fp->owner = owner; fp->ob = ob; return fp; } void copyflags(flagpile_t *dst, flagpile_t *src, int lifetime) { flag_t *f; for (f = src->first ; f ; f = f->next) { addflag_real(dst, f->id, f->val[0], f->val[1], f->val[2], f->text, (lifetime == NA) ? f->lifetime : lifetime, f->known); } } int flagstacks(enum FLAG fid) { int res = B_FALSE; switch (fid) { case F_EVASION: case F_BONUS: res = B_TRUE; break; default: res = B_FALSE; break; } return res; } flag_t *hasflag(flagpile_t *fp, int id) { return hasflag_real(fp, id, NA); } flag_t *hasflagknown(flagpile_t *fp, int id) { return hasflag_real(fp, id, B_TRUE); } flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown) { flag_t *f; lifeform_t *owner; owner = fp->owner; for (f = fp->first ; f ; f = f->next) { if (f->id == id) { int valid = B_TRUE; if ((wantknown != NA) && (f->known != wantknown)) valid = B_FALSE; if (owner && (f->lifetime == FROMJOB) && !getjob(owner)) { valid = B_FALSE; } if (valid) { return f; } } } 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); // doesn't have to be known } flag_t *hasflagvalknown(flagpile_t *fp, int id, int val1, int val2, int val3, char *text) { return hasflagval_real(fp, id, val1, val2, val3, text, B_TRUE); // must be known } flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, char *text, int wantknown) { flag_t *f; lifeform_t *owner; owner = fp->owner; for (f = fp->first ; f ; f = f->next) { if (f->id == id) { if (owner && (f->lifetime == FROMJOB) && !getjob(owner)) { // invalid } else { if ( ((val1 == NA) || (f->val[0] == val1)) && ((val2 == NA) || (f->val[1] == val2)) && ((val3 == NA) || (f->val[2] == val3)) && ((text == NULL) || strstr(f->text, text))) { if (!wantknown || f->known) { return f; } } } } } return NULL; } void killflagsofid(flagpile_t *fp, enum FLAG fid) { flag_t *f,*nextf; for (f = fp->first ; f ; f = nextf) { nextf = f->next; if (f->id == fid) { killflag(f); } } } void killflag(flag_t *f) { flag_t *nextone, *lastone; lifeform_t *lf; int needredraw = B_FALSE; lf = f->pile->owner; if (isplayer(lf)) { switch (f->id) { case F_BLIND: case F_SEEINDARK: needredraw = B_TRUE; break; default: break; } } // notify if (gamestarted) { if (f->pile->owner) { announceflagloss(f->pile->owner, f); } else if (f->pile->ob) { announceobflagloss(f->pile->ob, f); } } // we will revert to our original form at the end of timeeffectslf(). if (lf && (f->id == F_POLYMORPHED)) { lf->polyrevert = B_TRUE; } // free mem // remove from list nextone = f->next; if (nextone != NULL) { nextone->prev = f->prev; } else { /* last */ f->pile->last = f->prev; } if (f->prev == NULL) { /* first */ nextone = f->next; f->pile->first = nextone; free(f); } else { lastone = f->prev; free (lastone->next ); lastone->next = nextone; } if (gamestarted && needredraw) { drawscreen(); } } void killflagpile(flagpile_t *fp) { while (fp->first) { killflag(fp->first); } free(fp); } void timeeffectsflag(flag_t *f) { if ((f->lifetime != PERMENANT) && (f->lifetime > 0)) { f->lifetime--; if (f->lifetime <= 0) { killflag(f); return; } else if (f->lifetime == 5) { // warn about certain flags...... if (isplayer(f->pile->owner)) { switch (f->id) { case F_CANWILL: switch (f->val[0]) { case OT_A_JUMP: warn("Your ability to jump is starting to run out...");; break; default: break; } break; case F_DTIMMUNE: warn("Your %s immunity is starting to run out...", getdamname(f->val[0])); break; case F_DTRESIST: warn("Your %s resistance is starting to run out...", getdamname(f->val[0])); break; case F_DTVULN: warn("You feel a little less vulnerable to %s...", getdamname(f->val[0])); break; case F_MAGSHIELD: warn("Your magnetic shield is weakening..."); break; case F_POLYMORPHED: warn("You are starting to revert to your original form..."); break; default: // no message break; } } } else if (f->lifetime == 1) { // warn about certain flags...... if (isplayer(f->pile->owner)) { switch (f->id) { case F_CANWILL: switch (f->val[0]) { case OT_A_JUMP: warn("Your ability to jump is about to expire!");; break; default: break; } break; case F_DTIMMUNE: warn("Your %s immunity is about to expire!", getdamname(f->val[0])); break; case F_DTRESIST: warn("Your %s resistance is about to expire!", getdamname(f->val[0])); break; case F_DTVULN: warn("You feel a little less vulnerable to %s...", getdamname(f->val[0])); break; case F_MAGSHIELD: warn("Your magnetic shield is about to expire!"); break; case F_POLYMORPHED: warn("You are about to revert to your original form!"); break; default: // no message break; } } } } } void sumflags(flagpile_t *fp, int id, int *val0, int *val1, int *val2) { flag_t *f; if (val0) *val0 = 0; if (val1) *val1 = 0; if (val2) *val2 = 0; for (f = fp->first ; f ; f = f->next) { if (f->id == id) { if (val0) *val0 = *val0 + f->val[0]; if (val1) *val1 = *val1 + f->val[1]; if (val2) *val2 = *val2 + f->val[2]; } } } void timeeffectsflags(flagpile_t *fp) { flag_t *f,*nextf; for (f = fp->first ; f ; f = nextf) { nextf = f->next; timeeffectsflag(f); } }