diff --git a/attack.c b/attack.c index efeb954..7b4f8cf 100644 --- a/attack.c +++ b/attack.c @@ -1227,7 +1227,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) // victim's armour loses hp. note that it loses the full // amount of damage dealt, not just what it reduced. if (damreducedbyarmour && !critical) { - applyarmourdamage(victim, wep, dam[i], damtype[i], lf); + applyarmourdamage(victim, wep, dam[i] + damreducedbyarmour, damtype[i], lf); // train armour practice(victim, SK_ARMOUR, 1); } diff --git a/defs.h b/defs.h index 8f2f352..890f78a 100644 --- a/defs.h +++ b/defs.h @@ -719,6 +719,11 @@ enum SENSE { }; +enum GAINORLOSS { + GL_LOSS = 0, + GL_GAIN = 1, +}; + enum FLAGCONDITION { FC_NOCONDITION = 0, FC_IFPLAYER, @@ -3206,7 +3211,7 @@ enum FLAG { F_HASNEWLEVEL, // we have a new xp lev, but haven't trained yet. F_STATGAINREADY, // ready to increase str/int etc. v2 is how many times // we can do it. - F_INTERRUPTED, // somethign interrupted our rest. stop! + F_INTERRUPTED, // somethign interrupted our rest/training/eating. stop! F_EATING, // lf is eating obid v0 F_DIGGING, // v0/v1 = cell where lf is digging. // v2 is how much to dig per turn. diff --git a/flag.c b/flag.c index b9f2446..d3599a4 100644 --- a/flag.c +++ b/flag.c @@ -234,7 +234,11 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, if ( ((gamemode == GM_CHARGEN) && isplayer(f->pile->owner)) || ((gamemode == GM_GAMESTARTED) && announceflaggain(f->pile->owner, f)) ) { if (gamemode == GM_GAMESTARTED) { - // don't include flags which interrupt will kill! + if (flagcausesinterrupt(f, GL_GAIN)) { + addflag(f->pile, F_INTERRUPTED, B_TRUE, NA, NA, NULL); + } + // only some flags will interrupt player actions + /* switch (f->id) { case F_RUNNING: case F_TRAINING: @@ -250,6 +254,7 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, addflag(f->pile, F_INTERRUPTED, B_TRUE, NA, NA, NULL); break; } + */ } //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging @@ -528,6 +533,43 @@ int countflags(flagpile_t *fp) { return count; } +// returns TRUE if knowingly gaining/losing this flag will +// interrupt player actions like resting, training or eating. +int flagcausesinterrupt(flag_t *f, enum GAINORLOSS gol ) { + switch (f->id) { + case F_ASLEEP: + if (f->val[2] == NA) { // ie. sleeping, not resting + return B_TRUE; + } + break; + case F_BEINGSTONED: + case F_CONFUSED: + case F_FEIGNINGDEATH: + case F_FLYING: + case F_LEVITATING: + case F_NONCORPOREAL: + case F_PAIN: + case F_PARALYZED: + case F_POISONED: + case F_RAGE: + case F_SPRINTING: + case F_STUNNED: + return B_TRUE; + case F_BLIND: + case F_CAFFEINATED: + case F_DRUNK: + case F_FROZEN: + case F_GRABBEDBY: + case F_HOTFEET: + case F_INJURY: + case F_INVISIBLE: + if (gol == GL_GAIN) return B_TRUE; + break; + default: + break; + } + return B_FALSE; +} int flagcausesloscalc(enum FLAG fid) { switch (fid) { @@ -975,6 +1017,10 @@ void killflag(flag_t *f) { // announce if (announceflagloss(lf, f)) { + if (flagcausesinterrupt(f, GL_LOSS)) { + addflag(lf->flags, F_INTERRUPTED, B_TRUE, NA, NA, NULL); + } + /* // don't include flags which interrupt will kill! switch (f->id) { case F_RUNNING: @@ -991,6 +1037,7 @@ void killflag(flag_t *f) { addflag(lf->flags, F_INTERRUPTED, B_TRUE, NA, NA, NULL); break; } + */ } // special effects after announcement @@ -1194,38 +1241,38 @@ void timeeffectsflag(flag_t *f, int howlong) { case F_CANWILL: switch (f->val[0]) { case OT_A_JUMP: - warn("Your ability to jump is starting to run out...");; + msg("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])); + msg("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])); + msg("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])); + msg("You feel a little less vulnerable to %s...", getdamname(f->val[0])); break; case F_INVISIBLE: - warn("Your body is starting to reappear..."); + msg("Your body is starting to reappear..."); break; case F_MAGSHIELD: - warn("Your magnetic shield is weakening..."); + msg("Your magnetic shield is weakening..."); break; case F_POLYMORPHED: - warn("You are starting to revert to your original form..."); + msg("You are starting to revert to your original form..."); break; case F_LEVITATING: - warn("Your levitation is starting to expire..."); + msg("Your levitation is starting to expire..."); break; case F_FLYING: - warn("Your ability to fly is starting to expire..."); + msg("Your ability to fly is starting to expire..."); break; case F_SPIDERCLIMB: - warn("Your skin is becoming less adhesive..."); more(); + msg("Your skin is becoming less adhesive..."); more(); break; default: // no message break; @@ -1248,38 +1295,38 @@ void timeeffectsflag(flag_t *f, int howlong) { case F_CANWILL: switch (f->val[0]) { case OT_A_JUMP: - warn("Your ability to jump is about to expire!"); more(); + msg("Your ability to jump is about to expire!"); more(); break; default: break; } break; case F_DTIMMUNE: - warn("Your %s immunity is about to expire!", getdamname(f->val[0])); more(); + msg("Your %s immunity is about to expire!", getdamname(f->val[0])); more(); break; case F_DTRESIST: - warn("Your %s resistance is about to expire!", getdamname(f->val[0])); more(); + msg("Your %s resistance is about to expire!", getdamname(f->val[0])); more(); break; case F_DTVULN: - warn("You feel a little less vulnerable to %s...", getdamname(f->val[0])); + msg("You feel a little less vulnerable to %s...", getdamname(f->val[0])); break; case F_INVISIBLE: - warn("Your invisibility is about to expire!"); more(); + msg("Your invisibility is about to expire!"); more(); break; case F_MAGSHIELD: - warn("Your magnetic shield is about to expire!"); more(); + msg("Your magnetic shield is about to expire!"); more(); break; case F_LEVITATING: - warn("Your levitation is about to expire!"); more(); + msg("Your levitation is about to expire!"); more(); break; case F_SPIDERCLIMB: - warn("Your skin adhesion is about to expire!"); more(); + msg("Your skin adhesion is about to expire!"); more(); break; case F_POLYMORPHED: - warn("You are about to revert to your original form!"); more(); + msg("You are about to revert to your original form!"); more(); break; case F_FLYING: - warn("Your ability to fly is about to expire!"); more(); + msg("Your ability to fly is about to expire!"); more(); break; default: // no message break; diff --git a/flag.h b/flag.h index 88f0071..5cad14e 100644 --- a/flag.h +++ b/flag.h @@ -17,6 +17,7 @@ void checkflagpile(flagpile_t *fp); 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 flagcausesinterrupt(flag_t *f, enum GAINORLOSS gol); int flagcausesloscalc(enum FLAG fid); int flagcausesredraw(lifeform_t *lf, enum FLAG fid); int flagcausesstatredraw(lifeform_t *lf, enum FLAG fid); diff --git a/io.c b/io.c index d955629..c5bef52 100644 --- a/io.c +++ b/io.c @@ -2221,7 +2221,7 @@ int announceflagloss(lifeform_t *lf, flag_t *f) { msg("%s no longer looks quite so friendly!", lfname); break; case F_POISONED: - msg("%s %s less sick now.", lfname, isplayer(lf) ? "feel" : "looks"); + msg("^%c%s %s less sick now.^n", getlfcol(lf, CC_VGOOD), lfname, isplayer(lf) ? "feel" : "looks"); donesomething = B_TRUE; break; case F_HEAVENARM: @@ -3756,7 +3756,7 @@ void describerace(enum RACE rid) { // title if (gamemode == GM_GAMESTARTED) { enum SKILLLEVEL slev; - slev = getlorelevel(player, rid); + slev = getlorelevel(player, r->raceclass->id); snprintf(buf, BUFLEN, "Race::%s (%s level lore)",r->name, getskilllevelname(slev)); } else { snprintf(buf, BUFLEN, "Race::%s",r->name); @@ -6786,10 +6786,12 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel flagpile_t *doneflags; enum SKILLLEVEL lorelev; + r = findrace(rid); + if (forplayersel) { lorelev = PR_MASTER; } else { - lorelev = getlorelevel(player, rid); + lorelev = getlorelevel(player, r->raceclass->id); } // Your Lore skill for this race will determine how much information is shown. @@ -6808,8 +6810,6 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel strcpy(retbuf, ""); - r = findrace(rid); - if (showextra) { int a,n; int curidx,donesomething; diff --git a/lf.c b/lf.c index a6e61c0..b692859 100644 --- a/lf.c +++ b/lf.c @@ -14931,8 +14931,9 @@ int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground, int want getprayedgods(retgod, &nretgods); for (i = 0 ; i < nretgods; i++) { if (lfhasflagval(retgod[i], F_GODPOISON, B_FALSE, NA, NA, NULL)) { - // warn... - godsay(retgod[i]->race->id, B_TRUE, "I hope you're not planning on using that..."); + char warnbuf[BUFLEN]; + sprintf(warnbuf, "I hope you're not planning on using %s...", (o->amt == 1) ? "that" : "those"); + godsay(retgod[i]->race->id, B_TRUE, warnbuf); break; } } @@ -18039,12 +18040,14 @@ void startlfturn(lifeform_t *lf) { killflag(f); } else { flag_t *asleep; + int ko; // being asleep helps. asleep = hasflag(lf->flags, F_ASLEEP); + ko = isunconscious(lf); // chance of losing hp - if (pctchance(pt->dampct)) { + if (!ko && pctchance(pt->dampct)) { char buf[BUFLEN]; - if (!asleep && (isplayer(lf) || cansee(player, lf))) { + if (isplayer(lf) || cansee(player, lf)) { char *p; char lfname[BUFLEN],lfnameposs[BUFLEN]; getlfname(lf, lfname); @@ -18053,33 +18056,49 @@ void startlfturn(lifeform_t *lf) { p = strdup(pt->damverb); if (isplayer(lf)) { p = strrep(p, "YOUR", "Your", NULL); - p = strrep(p, "YOU", "You", NULL); + if (asleep) { + p = strrep(p, "YOU", "You wake up and", NULL); + } else { + p = strrep(p, "YOU", "You", NULL); + } p = strrep(p, "#S", "", NULL); } else { p = strrep(p, "YOUR", lfnameposs, NULL); - p = strrep(p, "YOU", lfname, NULL); + if (asleep) { + char replacetext[BUFLEN]; + sprintf(replacetext, "%s wakes and", lfname); + p = strrep(p, "YOU", replacetext, NULL); + } else { + p = strrep(p, "YOU", lfname, NULL); + } p = strrep(p, "#S", "s", NULL); } msg("%s", p); free(p); - taketime(lf, getactspeed(lf)); + if (asleep) { + int origborn; + origborn = lf->born; + lf->born = B_FALSE; // supress a second announcement of waking up + killflagsofid(lf->flags, F_ASLEEP); + lf->born = origborn; + } else { + taketime(lf, getactspeed(lf)); + } } snprintf(buf, BUFLEN, "%s^from %s",pt->name, f->text); losehp(lf, pt->dam * f->val[1], DT_DIRECT, NULL, buf); - if (!asleep) { - if (pt->vomitob != OT_NONE) { - addobfast(lf->cell->obpile, pt->vomitob); - } - loseconcentration(lf); + if (pt->vomitob != OT_NONE) { + addobfast(lf->cell->obpile, pt->vomitob); } + loseconcentration(lf); } // extra effects - if (f->val[0] == P_COLD) { + if (!ko && (f->val[0] == P_COLD)) { if (rnd(1,100) <= 10) { object_t *wep; if (isplayer(lf)) { @@ -18095,11 +18114,11 @@ void startlfturn(lifeform_t *lf) { getobname(wep, wname, 1); drop(wep, wep->amt); } - loseconcentration(lf); } } else if (f->val[0] == P_MIGRAINE) { - if (!asleep) { + // sleeping will avoid all migraine effects + if (!asleep && !ko) { int amt; amt = lfproduceslight(lf); if (amt) { diff --git a/spell.c b/spell.c index 2ffdc26..0c533d2 100644 --- a/spell.c +++ b/spell.c @@ -12475,7 +12475,7 @@ int spellresisted(lifeform_t *target, lifeform_t *caster, int spellid, int power if ((spellid == OT_S_SLEEP) && lfhasflag(target, F_RAGE)) { bonus += 10; } - if (hassubjob(caster, SJ_SCOURGE) && (spellid == OT_S_NULLIFY)) { + if (caster && hassubjob(caster, SJ_SCOURGE) && (spellid == OT_S_NULLIFY)) { // cancel out the difficulty from NULLIFY being a level 4 spell bonus += 8; }