- [+] skilled evasion: auto dodge fatal melee attacks if you have

stamina (costs all stamina) 
    - [+] f_dodges only works on fatal attacks
    - [+] for players, you lose all stamina afterwards
    - [+] for mosnters, just a straight 1 in 3 chance.
    - [+] TEST!
- [+] bug: water spray spell doing massive damage?
This commit is contained in:
Rob Pearce 2012-02-22 12:05:02 +00:00
parent 0f914d8819
commit 67b00b1dc0
4 changed files with 52 additions and 23 deletions

View File

@ -592,7 +592,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
int deflected = B_FALSE; int deflected = B_FALSE;
int weppassthrough = B_FALSE; int weppassthrough = B_FALSE;
int firstisbackstab = B_FALSE; int firstisbackstab = B_FALSE;
int blocked = B_FALSE; int blocked = B_FALSE,dodged = B_FALSE;
int hit = B_FALSE; int hit = B_FALSE;
int critical = 0; int critical = 0;
char wepname[BUFLEN]; char wepname[BUFLEN];
@ -993,8 +993,8 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
} }
// at this point, will the damage be fatal? we need to know so we // at this point, will the damage be fatal? we need to know so we
// can determine whether monsters will use feign death ability. // can determine whether monsters will use feign death or dodge abilities.
// NOTE: whether or not the atatck is fatal is re-calculated again // NOTE: whether or not the attack is fatal is re-calculated again
// later on after damage is applied to ensure that the correct // later on after damage is applied to ensure that the correct
// attack string is displayed ("you hit xxx" vs "you kill xxx"). // attack string is displayed ("you hit xxx" vs "you kill xxx").
if (dam[i] >= victim->hp) { if (dam[i] >= victim->hp) {
@ -1014,6 +1014,50 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
} }
} }
if (fatal && !feigneddeath && lfhasflag(victim, F_DODGES) && cansee(victim, lf) && hasfreeaction(victim)) {
cell_t *adj;
int candodge = B_FALSE;
if (isplayer(victim)) {
if (getstamina(victim)) {
candodge = B_TRUE;
}
} else if (onein(3)) {
candodge = B_TRUE;
}
if (candodge) {
adj = getrandomadjcell(victim->cell, WE_WALKABLE, B_NOEXPAND);
if (adj) {
flag_t *f;
if (isplayer(victim) || cansee(player, victim)) {
if (cansee(player, lf)) {
msg("^w%s dodge%s %s%s attack!",victimname,isplayer(victim) ? "" : "s",
attackername, getpossessive(attackername));
} else {
msg("^w%s dodge%s an attack!",victimname,isplayer(victim) ? "" : "s");
}
} else if (isplayer(lf)) {
msg("You attack something, but it dodges!");
} else if (cansee(player, lf)) {
msg("%s attacks something, but it dodges!", attackername);
}
f = addflag(victim->flags, F_NOTIME, B_TRUE, NA, NA, NULL);
moveto(victim, adj, B_FALSE, B_FALSE);
killflag(f);
if (isplayer(victim)) {
setstamina(victim, 0);
}
// remember that we dodged, to avoid otehr attack effects like
// heavy blow, etc.
dodged = B_TRUE;
// stop processing now.
break;
}
}
}
if (willheal) { if (willheal) {
if (cansee(player, victim)) { if (cansee(player, victim)) {
flag_t *f; flag_t *f;
@ -1108,13 +1152,12 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
if (fatal || waskod) break; // stop now! if (fatal || waskod) break; // stop now!
} // end foreach damtype } // end foreach damtype
if (waskod) { if (waskod) {
loseconsciousness(victim, waskod, lf); loseconsciousness(victim, waskod, lf);
} }
// other effects // other effects
if (!isdead(victim) && !blocked) { if (!isdead(victim) && !blocked && !dodged) {
// special weapon effects, as long as you're not doing a heavy blow // special weapon effects, as long as you're not doing a heavy blow
if (!lfhasflag(lf, F_HEAVYBLOW) && dam[0]) { if (!lfhasflag(lf, F_HEAVYBLOW) && dam[0]) {
wepeffects(wep->flags, victim->cell, damflag, dam[0]); wepeffects(wep->flags, victim->cell, damflag, dam[0]);
@ -1224,7 +1267,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
} // end if !isdead(victim) } // end if !isdead(victim)
// retaliation happens even if victim died // retaliation happens even if victim died
if (!blocked) { if (!blocked && !dodged) {
getflags(victim->flags, retflag, &nretflags, F_RETALIATE, F_NONE); getflags(victim->flags, retflag, &nretflags, F_RETALIATE, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
@ -1276,22 +1319,6 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
// train evasion // train evasion
practice(victim, SK_EVASION, 1); practice(victim, SK_EVASION, 1);
if (lfhasflag(victim, F_DODGES)) {
cell_t *adj;
adj = getrandomadjcell(victim->cell, WE_WALKABLE, B_NOEXPAND);
if (adj) {
flag_t *f;
if (isplayer(victim) || cansee(player, victim)) {
msg("^w%s dodge%s!",victimname,isplayer(victim) ? "" : "s");
}
f = addflag(victim->flags, F_NOTIME, B_TRUE, NA, NA, NULL);
moveto(victim, adj, B_FALSE, B_FALSE);
killflag(f);
}
}
// chance that ai will give up if we can't reach the victim // chance that ai will give up if we can't reach the victim
if (!isplayer(lf) && !canreach(lf, victim, NULL)) { if (!isplayer(lf) && !canreach(lf, victim, NULL)) {
if (pctchance(90)) { if (pctchance(90)) {

1
data.c
View File

@ -12740,6 +12740,7 @@ void initskills(void) {
addskilldesc(SK_EVASION, PR_ADEPT, "^gIncreases your EV by 36%.^n", B_FALSE); addskilldesc(SK_EVASION, PR_ADEPT, "^gIncreases your EV by 36%.^n", B_FALSE);
addskilldesc(SK_EVASION, PR_ADEPT, "^gYou gain the 'snatch' ability.^n", B_FALSE); addskilldesc(SK_EVASION, PR_ADEPT, "^gYou gain the 'snatch' ability.^n", B_FALSE);
addskilldesc(SK_EVASION, PR_SKILLED, "^gIncreases your EV by 48%.^n", B_FALSE); addskilldesc(SK_EVASION, PR_SKILLED, "^gIncreases your EV by 48%.^n", B_FALSE);
addskilldesc(SK_EVASION, PR_SKILLED, "^gYou now automatically dodge fatal attacks if you have free stamina.^n", B_FALSE);
addskilldesc(SK_EVASION, PR_EXPERT, "^gIncreases your EV by 60%.^n", B_FALSE); addskilldesc(SK_EVASION, PR_EXPERT, "^gIncreases your EV by 60%.^n", B_FALSE);
addskilldesc(SK_EVASION, PR_MASTER, "^gIncreases your EV by 72%.^n", B_FALSE); addskilldesc(SK_EVASION, PR_MASTER, "^gIncreases your EV by 72%.^n", B_FALSE);
addskill(SK_FIRSTAID, "First Aid", "Increases your healing rate and reduces duration of poison.", 0); // untrainable addskill(SK_FIRSTAID, "First Aid", "Increases your healing rate and reduces duration of poison.", 0); // untrainable

2
lf.c
View File

@ -9541,6 +9541,8 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
if (isplayer(lf)) { if (isplayer(lf)) {
newf = addtempflag(lf->flags, F_CANWILL, OT_A_SNATCH, NA, NA, NULL, FROMSKILL); newf = addtempflag(lf->flags, F_CANWILL, OT_A_SNATCH, NA, NA, NULL, FROMSKILL);
} }
} else if (f->val[1] == PR_SKILLED) {
newf = addtempflag(lf->flags, F_DODGES, B_TRUE, NA, NA, NULL, FROMSKILL);
} }
} else if (id == SK_LORE_ARCANA) { } else if (id == SK_LORE_ARCANA) {
if (f->val[1] == PR_ADEPT) { if (f->val[1] == PR_ADEPT) {

View File

@ -10878,7 +10878,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
int dir,amt, n; int dir,amt, n;
object_t *arm[MAXBODYPARTS]; object_t *arm[MAXBODYPARTS];
int narm = 0; int narm = 0;
int dam;
getlfname(target, lfname); getlfname(target, lfname);
// hit // hit
if (cansee(player, target)) { if (cansee(player, target)) {