jousting
Part I: it's possible to use two-weapon combat while wielding a
lance (which seems odd to me); the second weapon would hit even if the
the first delivered a lance jousting blow that knocked the target away.
Part II: always getting the joust knockback effect when hitting
with a lance while mounted was too powerful; implement a suggestion
from the newsgroup that it be a random chance based on skill level.
Related: it's now possible to break your lance when hitting; when
adding that, I noticed that it was theoretically possible (didn't try
to reproduce) for a shattered boomerang or mirror to yield the stagger
bonus sometimes given for unarmed attacks.
This commit is contained in:
@@ -316,6 +316,8 @@ don't crash teleporting out of a monster while engulfed, punished but not
|
|||||||
carrying the ball
|
carrying the ball
|
||||||
web breaking should consider steed strength and other characteristics
|
web breaking should consider steed strength and other characteristics
|
||||||
various missing or inappropriate "killed by" death messages
|
various missing or inappropriate "killed by" death messages
|
||||||
|
second attack for two-weapon combat will miss if first knocks target away
|
||||||
|
jousting effect no longer occurs every time riding character hits with lance
|
||||||
|
|
||||||
|
|
||||||
Platform- and/or Interface-Specific Fixes
|
Platform- and/or Interface-Specific Fixes
|
||||||
|
|||||||
81
src/uhitm.c
81
src/uhitm.c
@@ -1,4 +1,4 @@
|
|||||||
/* SCCS Id: @(#)uhitm.c 3.4 2002/11/07 */
|
/* SCCS Id: @(#)uhitm.c 3.4 2002/11/29 */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -8,6 +8,10 @@ STATIC_DCL boolean FDECL(known_hitum, (struct monst *,int *,struct attack *));
|
|||||||
STATIC_DCL void FDECL(steal_it, (struct monst *, struct attack *));
|
STATIC_DCL void FDECL(steal_it, (struct monst *, struct attack *));
|
||||||
STATIC_DCL boolean FDECL(hitum, (struct monst *,int,struct attack *));
|
STATIC_DCL boolean FDECL(hitum, (struct monst *,int,struct attack *));
|
||||||
STATIC_DCL boolean FDECL(hmon_hitmon, (struct monst *,struct obj *,int));
|
STATIC_DCL boolean FDECL(hmon_hitmon, (struct monst *,struct obj *,int));
|
||||||
|
#ifdef STEED
|
||||||
|
STATIC_DCL int FDECL(joust, (struct monst *,struct obj *));
|
||||||
|
#endif
|
||||||
|
STATIC_DCL void NDECL(demonpet);
|
||||||
STATIC_DCL boolean FDECL(m_slips_free, (struct monst *mtmp,struct attack *mattk));
|
STATIC_DCL boolean FDECL(m_slips_free, (struct monst *mtmp,struct attack *mattk));
|
||||||
STATIC_DCL int FDECL(explum, (struct monst *,struct attack *));
|
STATIC_DCL int FDECL(explum, (struct monst *,struct attack *));
|
||||||
STATIC_DCL void FDECL(start_engulf, (struct monst *));
|
STATIC_DCL void FDECL(start_engulf, (struct monst *));
|
||||||
@@ -419,17 +423,20 @@ struct attack *uattk;
|
|||||||
if(!*mhit) {
|
if(!*mhit) {
|
||||||
missum(mon, uattk);
|
missum(mon, uattk);
|
||||||
} else {
|
} else {
|
||||||
int oldhp = mon->mhp;
|
int oldhp = mon->mhp,
|
||||||
|
x = u.ux + u.dx, y = u.uy + u.dy;
|
||||||
|
|
||||||
/* KMH, conduct */
|
/* KMH, conduct */
|
||||||
if (uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep)))
|
if (uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep)))
|
||||||
u.uconduct.weaphit++;
|
u.uconduct.weaphit++;
|
||||||
|
|
||||||
/* we hit the monster; be careful: it might die! */
|
/* we hit the monster; be careful: it might die or
|
||||||
notonhead = (mon->mx != u.ux+u.dx || mon->my != u.uy+u.dy);
|
be knocked into a different location */
|
||||||
|
notonhead = (mon->mx != x || mon->my != y);
|
||||||
malive = hmon(mon, uwep, 0);
|
malive = hmon(mon, uwep, 0);
|
||||||
/* This assumes that Stormbringer was uwep not uswapwep */
|
/* this assumes that Stormbringer was uwep not uswapwep */
|
||||||
if (malive && u.twoweap && !override_confirmation)
|
if (malive && u.twoweap && !override_confirmation &&
|
||||||
|
m_at(x, y) == mon)
|
||||||
malive = hmon(mon, uswapwep, 0);
|
malive = hmon(mon, uswapwep, 0);
|
||||||
if (malive) {
|
if (malive) {
|
||||||
/* monster still alive */
|
/* monster still alive */
|
||||||
@@ -453,7 +460,7 @@ struct attack *uattk;
|
|||||||
--u.uconduct.weaphit;
|
--u.uconduct.weaphit;
|
||||||
}
|
}
|
||||||
if (mon->wormno && *mhit)
|
if (mon->wormno && *mhit)
|
||||||
cutworm(mon, u.ux+u.dx, u.uy+u.dy, uwep);
|
cutworm(mon, x, y, uwep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(malive);
|
return(malive);
|
||||||
@@ -512,10 +519,11 @@ int thrown;
|
|||||||
boolean get_dmg_bonus = TRUE;
|
boolean get_dmg_bonus = TRUE;
|
||||||
boolean ispoisoned = FALSE, needpoismsg = FALSE, poiskilled = FALSE;
|
boolean ispoisoned = FALSE, needpoismsg = FALSE, poiskilled = FALSE;
|
||||||
boolean silvermsg = FALSE;
|
boolean silvermsg = FALSE;
|
||||||
#ifdef STEED
|
|
||||||
boolean jousting = FALSE;
|
|
||||||
#endif
|
|
||||||
boolean valid_weapon_attack = FALSE;
|
boolean valid_weapon_attack = FALSE;
|
||||||
|
boolean unarmed = !uwep && !uarm && !uarms;
|
||||||
|
#ifdef STEED
|
||||||
|
int jousting = 0;
|
||||||
|
#endif
|
||||||
int wtype;
|
int wtype;
|
||||||
struct obj *monwep;
|
struct obj *monwep;
|
||||||
char yourbuf[BUFSZ];
|
char yourbuf[BUFSZ];
|
||||||
@@ -620,9 +628,12 @@ int thrown;
|
|||||||
&& hates_silver(mdat))
|
&& hates_silver(mdat))
|
||||||
silvermsg = TRUE;
|
silvermsg = TRUE;
|
||||||
#ifdef STEED
|
#ifdef STEED
|
||||||
if (u.usteed && !thrown &&
|
if (u.usteed && !thrown && tmp > 0 &&
|
||||||
weapon_type(obj) == P_LANCE && mon != u.ustuck)
|
weapon_type(obj) == P_LANCE && mon != u.ustuck) {
|
||||||
jousting = TRUE;
|
jousting = joust(mon, obj);
|
||||||
|
/* exercise skill even for minimal damage hits */
|
||||||
|
if (jousting) valid_weapon_attack = TRUE;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if(!thrown && obj == uwep && obj->otyp == BOOMERANG &&
|
if(!thrown && obj == uwep && obj->otyp == BOOMERANG &&
|
||||||
!rnl(3)) {
|
!rnl(3)) {
|
||||||
@@ -679,6 +690,8 @@ int thrown;
|
|||||||
change_luck(-2);
|
change_luck(-2);
|
||||||
useup(obj);
|
useup(obj);
|
||||||
obj = (struct obj *) 0;
|
obj = (struct obj *) 0;
|
||||||
|
unarmed = FALSE; /* avoid obj==0 confusion */
|
||||||
|
get_dmg_bonus = FALSE;
|
||||||
hittxt = TRUE;
|
hittxt = TRUE;
|
||||||
}
|
}
|
||||||
tmp = 1;
|
tmp = 1;
|
||||||
@@ -908,8 +921,15 @@ int thrown;
|
|||||||
|
|
||||||
#ifdef STEED
|
#ifdef STEED
|
||||||
if (jousting) {
|
if (jousting) {
|
||||||
|
tmp += d(2, (obj == uwep) ? 10 : 2); /* [was in dmgval()] */
|
||||||
You("joust %s%s",
|
You("joust %s%s",
|
||||||
mon_nam(mon), canseemon(mon) ? exclam(tmp) : ".");
|
mon_nam(mon), canseemon(mon) ? exclam(tmp) : ".");
|
||||||
|
if (jousting < 0) {
|
||||||
|
Your("%s shatters on impact!", doname(obj));
|
||||||
|
/* minor side-effect: broken lance won't split puddings */
|
||||||
|
useup(obj);
|
||||||
|
obj = 0;
|
||||||
|
}
|
||||||
/* avoid migrating a dead monster */
|
/* avoid migrating a dead monster */
|
||||||
if (mon->mhp > tmp) {
|
if (mon->mhp > tmp) {
|
||||||
mhurtle(mon, u.dx, u.dy, 1);
|
mhurtle(mon, u.dx, u.dy, 1);
|
||||||
@@ -920,7 +940,7 @@ int thrown;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* VERY small chance of stunning opponent if unarmed. */
|
/* VERY small chance of stunning opponent if unarmed. */
|
||||||
if (tmp > 1 && !thrown && !obj && !uwep && !uarm && !uarms && !Upolyd) {
|
if (unarmed && tmp > 1 && !thrown && !obj && !Upolyd) {
|
||||||
if (rnd(100) < P_SKILL(P_BARE_HANDED_COMBAT) &&
|
if (rnd(100) < P_SKILL(P_BARE_HANDED_COMBAT) &&
|
||||||
!bigmonst(mdat) && !thick_skinned(mdat)) {
|
!bigmonst(mdat) && !thick_skinned(mdat)) {
|
||||||
if (canspotmon(mon))
|
if (canspotmon(mon))
|
||||||
@@ -1051,7 +1071,32 @@ struct attack *mattk;
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC_DCL void NDECL(demonpet);
|
/* used when hitting a monster with a lance while mounted */
|
||||||
|
STATIC_OVL int /* 1: joust hit; 0: ordinary hit; -1: joust but break lance */
|
||||||
|
joust(mon, obj)
|
||||||
|
struct monst *mon; /* target */
|
||||||
|
struct obj *obj; /* weapon */
|
||||||
|
{
|
||||||
|
int skill_rating, joust_dieroll;
|
||||||
|
|
||||||
|
if (Fumbling || Stunned) return 0;
|
||||||
|
|
||||||
|
/* if using two weapons, use worse of lance and two-weapon skills */
|
||||||
|
skill_rating = P_SKILL(weapon_type(obj)); /* lance skill */
|
||||||
|
if (u.twoweap && P_SKILL(P_TWO_WEAPON_COMBAT) < skill_rating)
|
||||||
|
skill_rating = P_SKILL(P_TWO_WEAPON_COMBAT);
|
||||||
|
if (skill_rating == P_ISRESTRICTED) skill_rating = P_UNSKILLED; /* 0=>1 */
|
||||||
|
|
||||||
|
/* odds to joust are expert:80%, skilled:60%, basic:40%, unskilled:20% */
|
||||||
|
if ((joust_dieroll = rn2(5)) < skill_rating) {
|
||||||
|
if (joust_dieroll == 0 && rnl(50) == (50-1) &&
|
||||||
|
!unsolid(mon->data) && !obj_resists(obj, 0, 100))
|
||||||
|
return -1; /* hit that breaks lance */
|
||||||
|
return 1; /* successful joust */
|
||||||
|
}
|
||||||
|
return 0; /* no joust bonus; revert to ordinary attack */
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send in a demon pet for the hero. Exercise wisdom.
|
* Send in a demon pet for the hero. Exercise wisdom.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -286,13 +286,6 @@ struct monst *mon;
|
|||||||
otmp->oclass == BALL_CLASS || otmp->oclass == CHAIN_CLASS) {
|
otmp->oclass == BALL_CLASS || otmp->oclass == CHAIN_CLASS) {
|
||||||
int bonus = 0;
|
int bonus = 0;
|
||||||
|
|
||||||
#ifdef STEED
|
|
||||||
/* KMH -- Lances are especially made for riding */
|
|
||||||
if (otmp == uwep && u.usteed &&
|
|
||||||
objects[otmp->otyp].oc_skill == P_LANCE)
|
|
||||||
bonus += d(2,10);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (otmp->blessed && (is_undead(ptr) || is_demon(ptr)))
|
if (otmp->blessed && (is_undead(ptr) || is_demon(ptr)))
|
||||||
bonus += rnd(4);
|
bonus += rnd(4);
|
||||||
if (is_axe(otmp) && is_wooden(ptr))
|
if (is_axe(otmp) && is_wooden(ptr))
|
||||||
|
|||||||
Reference in New Issue
Block a user