kicking vs throwing vs polearms (trunk only)

Wielding a bow while kicking arrows gave a shooting bonus.  Also,
From a bug report:  applying a
polearm to hit at range never caused a pudding to split because the attack
gets treated as throwing.  Likewise, confuse monster effect (hands glowing
red) didn't kick in for applied polearms.
This commit is contained in:
nethack.rankin
2007-03-25 05:31:13 +00:00
parent 1c4907829d
commit ae9c10ea07
5 changed files with 57 additions and 30 deletions

View File

@@ -200,6 +200,8 @@ artifacts which subsequently evade your grasp/control after already being
hero with lycanthropy is vulnerable to silver in human form as well as beast
changing alignment or shape triggers a check for equipment evading hero's grasp
passive fire effects can damage attackers weapons
wielded bow shouldn't affect outcome of kicked arrows
ranged polearm hit can divide puddings and can use confuse monster effect
Platform- and/or Interface-Specific Fixes

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)hack.h 3.5 2007/02/21 */
/* SCCS Id: @(#)hack.h 3.5 2007/03/24 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -129,6 +129,13 @@ NEARDATA extern coord bhitpos; /* place where throw or zap hits or stops */
#define FLASHED_LIGHT 3
#define INVIS_BEAM 4
/* attack mode for hmon() */
#define HMON_MELEE 0 /* hand-to-hand */
#define HMON_THROWN 1 /* normal ranged (or spitting while poly'd) */
#define HMON_KICKED 2 /* alternate ranged */
#define HMON_APPLIED 3 /* polearm, treated as ranged */
#define HMON_DRAGGED 4 /* attached iron ball, pulled into mon */
#define MATCH_WARN_OF_MON(mon) (Warn_of_mon && \
((context.warntype.obj && \
(context.warntype.obj & (mon)->data->mflags2)) || \

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)ball.c 3.5 2003/02/03 */
/* SCCS Id: @(#)ball.c 3.5 2007/03/24 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -585,7 +585,7 @@ drag:
tmp = -2 + Luck + find_mac(victim);
tmp += omon_adj(victim, uball, TRUE);
if (tmp >= rnd(20))
(void) hmon(victim,uball,1);
(void) hmon(victim, uball, HMON_DRAGGED);
else
miss(xname(uball), victim);

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)dothrow.c 3.5 2007/01/10 */
/* SCCS Id: @(#)dothrow.c 3.5 2007/03/23 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -27,6 +27,7 @@ static NEARDATA const char bullets[] =
struct obj *thrownobj = 0; /* tracks an object until it lands */
extern struct obj *kickobj; /* from dokick.c */
extern boolean notonhead; /* for long worms */
@@ -1225,23 +1226,28 @@ boolean maybe_wakeup;
}
#define quest_arti_hits_leader(obj,mon) \
(obj->oartifact && is_quest_artifact(obj) && (mon->data->msound == MS_LEADER))
(obj->oartifact && is_quest_artifact(obj) && \
mon->m_id == quest_status.leader_m_id)
/*
* Object thrown by player arrives at monster's location.
* Return 1 if obj has disappeared or otherwise been taken care of,
* 0 if caller must take care of it.
* Also used for kicked objects and for polearms/grapnel applied at range.
*/
int
thitmonst(mon, obj)
register struct monst *mon;
register struct obj *obj;
register struct obj *obj; /* thrownobj or kickobj or uwep */
{
register int tmp; /* Base chance to hit */
register int disttmp; /* distance modifier */
int otyp = obj->otyp;
int otyp = obj->otyp, hmode;
boolean guaranteed_hit = (u.uswallow && mon == u.ustuck);
hmode = (obj == uwep) ? HMON_APPLIED :
(obj == kickobj) ? HMON_KICKED : HMON_THROWN;
/* Differences from melee weapons:
*
* Dex still gives a bonus, but strength does not.
@@ -1287,8 +1293,8 @@ register struct obj *obj;
}
tmp += omon_adj(mon, obj, TRUE);
if (is_orc(mon->data) && maybe_polyd(is_elf(youmonst.data),
Race_if(PM_ELF)))
if (is_orc(mon->data) &&
maybe_polyd(is_elf(youmonst.data), Race_if(PM_ELF)))
tmp++;
if (guaranteed_hit) {
tmp += 1000; /* Guaranteed hit */
@@ -1308,8 +1314,9 @@ register struct obj *obj;
}
/* don't make game unwinnable if naive player throws artifact
at leader.... */
if (quest_arti_hits_leader(obj, mon)) {
at leader... (kicked artifact is ok too; HMON_APPLIED could
occur if quest artifact polearm or grapnel ever gets added) */
if (hmode != HMON_APPLIED && quest_arti_hits_leader(obj, mon)) {
/* not wakeup(), which angers non-tame monsters */
mon->msleeping = 0;
mon->mstrategy &= ~STRAT_WAITMASK;
@@ -1336,7 +1343,10 @@ register struct obj *obj;
if (obj->oclass == WEAPON_CLASS || is_weptool(obj) ||
obj->oclass == GEM_CLASS) {
if (is_ammo(obj)) {
if (hmode == HMON_KICKED) {
/* throwing adjustments and weapon skill bonus don't apply */
tmp -= (is_ammo(obj) ? 5 : 3);
} else if (is_ammo(obj)) {
if (!ammo_and_launcher(obj, uwep)) {
tmp -= 4;
} else {
@@ -1358,12 +1368,12 @@ register struct obj *obj;
tmp++;
}
}
} else {
} else { /* thrown non-ammo or applied polearm/grapnel */
if (otyp == BOOMERANG) /* arbitrary */
tmp += 4;
else if (throwing_weapon(obj)) /* meant to be thrown */
tmp += 2;
else /* not meant to be thrown */
else if (obj == thrownobj) /* not meant to be thrown */
tmp -= 2;
/* we know we're dealing with a weapon or weptool handled
by WEAPON_SKILLS once ammo objects have been excluded */
@@ -1371,7 +1381,7 @@ register struct obj *obj;
}
if (tmp >= rnd(20)) {
if (hmon(mon,obj,1)) { /* mon still alive */
if (hmon(mon, obj, hmode)) { /* mon still alive */
cutworm(mon, bhitpos.x, bhitpos.y, obj);
}
exercise(A_DEX, TRUE);
@@ -1411,7 +1421,7 @@ register struct obj *obj;
int was_swallowed = guaranteed_hit;
exercise(A_DEX, TRUE);
if (!hmon(mon,obj,1)) { /* mon killed */
if (!hmon(mon, obj, hmode)) { /* mon killed */
if (was_swallowed && !u.uswallow && obj == uball)
return 1; /* already did placebc() */
}
@@ -1423,7 +1433,7 @@ register struct obj *obj;
exercise(A_STR, TRUE);
if (tmp >= rnd(20)) {
exercise(A_DEX, TRUE);
(void) hmon(mon,obj,1);
(void) hmon(mon, obj, hmode);
} else {
tmiss(obj, mon, TRUE);
}
@@ -1431,7 +1441,7 @@ register struct obj *obj;
} else if ((otyp == EGG || otyp == CREAM_PIE ||
otyp == BLINDING_VENOM || otyp == ACID_VENOM) &&
(guaranteed_hit || ACURR(A_DEX) > rnd(25))) {
(void) hmon(mon, obj, 1);
(void) hmon(mon, obj, hmode);
return 1; /* hmon used it up */
} else if (obj->oclass == POTION_CLASS &&

View File

@@ -453,7 +453,7 @@ struct attack *uattk;
/* we hit the monster; be careful: it might die or
be knocked into a different location */
notonhead = (mon->mx != x || mon->my != y);
malive = hmon(mon, weapon, 0);
malive = hmon(mon, weapon, HMON_MELEE);
if (malive) {
/* monster still alive */
if(!rn2(25) && mon->mhp < mon->mhpmax/2
@@ -514,7 +514,7 @@ boolean /* general "damage monster" routine */
hmon(mon, obj, thrown) /* return TRUE if mon still alive */
struct monst *mon;
struct obj *obj;
int thrown;
int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
{
boolean result, anger_guards;
@@ -533,7 +533,7 @@ STATIC_OVL boolean
hmon_hitmon(mon, obj, thrown)
struct monst *mon;
struct obj *obj;
int thrown;
int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
{
int tmp;
struct permonst *mdat = mon->data;
@@ -605,7 +605,8 @@ int thrown;
#endif
is_pole(obj)) ||
/* or throw a missile without the proper bow... */
(is_ammo(obj) && !ammo_and_launcher(obj, uwep))) {
(is_ammo(obj) && (thrown != HMON_THROWN ||
!ammo_and_launcher(obj, uwep)))) {
/* then do only 1-2 points of damage */
if (mdat == &mons[PM_SHADE] && obj->otyp != SILVER_ARROW)
tmp = 0;
@@ -690,7 +691,8 @@ int thrown;
if (jousting) valid_weapon_attack = TRUE;
}
#endif
if (thrown && (is_ammo(obj) || is_missile(obj))) {
if (thrown == HMON_THROWN &&
(is_ammo(obj) || is_missile(obj))) {
if (ammo_and_launcher(obj, uwep)) {
/* Elves and Samurai do extra damage using
* their bows&arrows; they're highly trained.
@@ -924,7 +926,8 @@ int thrown;
/* If you throw using a propellor, you don't get a strength
* bonus but you do get an increase-damage bonus.
*/
if(!thrown || !obj || !uwep || !ammo_and_launcher(obj, uwep))
if (thrown != HMON_THROWN || !obj || !uwep ||
!ammo_and_launcher(obj, uwep))
tmp += dbon();
}
@@ -1027,11 +1030,15 @@ int thrown;
abuse_dog(mon);
monflee(mon, 10 * rnd(tmp), FALSE, FALSE);
}
if((mdat == &mons[PM_BLACK_PUDDING] || mdat == &mons[PM_BROWN_PUDDING])
&& obj && obj == uwep
&& objects[obj->otyp].oc_material == IRON
&& mon->mhp > 1 && !thrown && !mon->mcan
/* && !destroyed -- guaranteed by mhp > 1 */ ) {
if ((mdat == &mons[PM_BLACK_PUDDING] ||
mdat == &mons[PM_BROWN_PUDDING]) &&
/* pudding is alive and healthy enough to split */
mon->mhp > 1 && !mon->mcan &&
/* iron weapon using melee or polearm hit */
obj && obj == uwep &&
objects[obj->otyp].oc_material == IRON &&
(thrown == HMON_MELEE ||
(thrown == HMON_APPLIED && is_pole(obj)))) {
if (clone_mon(mon, 0, 0)) {
pline("%s divides as you hit it!", Monnam(mon));
hittxt = TRUE;
@@ -1085,7 +1092,8 @@ int thrown;
} else if (destroyed) {
if (!already_killed)
killed(mon); /* takes care of most messages */
} else if(u.umconf && !thrown) {
} else if (u.umconf &&
(thrown == HMON_MELEE || thrown == HMON_APPLIED)) {
nohandglow(mon);
if (!mon->mconf && !resist(mon, SPBOOK_CLASS, 0, NOTELL)) {
mon->mconf = 1;