@@ -1476,10 +1476,11 @@ throwit(struct obj *obj,
|
||||
{
|
||||
struct monst *mon;
|
||||
int range, urange;
|
||||
const struct throw_and_return_weapon *arw = autoreturn_weapon(obj);
|
||||
boolean crossbowing,
|
||||
impaired = (Confusion || Stunned || Blind
|
||||
|| Hallucination || Fumbling),
|
||||
tethered_weapon = (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0);
|
||||
tethered_weapon = (arw && arw->tethered && (wep_mask & W_WEP) != 0);
|
||||
|
||||
gn.notonhead = FALSE; /* reset potentially stale value */
|
||||
if ((obj->cursed || obj->greased) && (u.dx || u.dy) && !rn2(7)) {
|
||||
@@ -1616,9 +1617,9 @@ throwit(struct obj *obj,
|
||||
else if (is_art(obj, ART_MJOLLNIR))
|
||||
range = (range + 1) / 2; /* it's heavy */
|
||||
else if (tethered_weapon) /* primary weapon is aklys */
|
||||
/* if an aklys is going to return, range is limited by the
|
||||
/* range of a tethered_weapon is limited by the
|
||||
length of the attached cord [implicit aspect of item] */
|
||||
range = min(range, BOLT_LIM / 2);
|
||||
range = min(range, arw->range);
|
||||
else if (obj == uball && u.utrap && u.utraptype == TT_INFLOOR)
|
||||
range = 1;
|
||||
|
||||
|
||||
@@ -470,7 +470,7 @@ mattacku(struct monst *mtmp)
|
||||
struct permonst *mdat = mtmp->data;
|
||||
/*
|
||||
* ranged: Is it near you? Affects your actions.
|
||||
* ranged2: Does it think it's near you? Affects its actions.
|
||||
* range2: Does it think it's near you? Affects its actions.
|
||||
* foundyou: Is it attacking you or your image?
|
||||
* youseeit: Can you observe the attack? It might be attacking your
|
||||
* image around the corner, or invisible, or you might be blind.
|
||||
@@ -497,11 +497,10 @@ mattacku(struct monst *mtmp)
|
||||
return 0;
|
||||
u.ustuck->mux = u.ux;
|
||||
u.ustuck->muy = u.uy;
|
||||
range2 = 0;
|
||||
foundyou = 1;
|
||||
if (u.uinvulnerable)
|
||||
return 0; /* stomachs can't hurt you! */
|
||||
|
||||
range2 = 0;
|
||||
foundyou = 1;
|
||||
} else if (u.usteed) {
|
||||
if (mtmp == u.usteed)
|
||||
/* Your steed won't attack you */
|
||||
|
||||
@@ -23,7 +23,7 @@ staticfn int postmov(struct monst *, struct permonst *, coordxy, coordxy, int,
|
||||
unsigned, boolean, boolean, boolean) NONNULLPTRS;
|
||||
staticfn boolean leppie_avoidance(struct monst *);
|
||||
staticfn void leppie_stash(struct monst *);
|
||||
staticfn boolean m_balks_at_approaching(struct monst *);
|
||||
staticfn int m_balks_at_approaching(int, struct monst *, int *, int *);
|
||||
staticfn boolean stuff_prevents_passage(struct monst *);
|
||||
staticfn int vamp_shift(struct monst *, struct permonst *, boolean);
|
||||
staticfn void maybe_spin_web(struct monst *);
|
||||
@@ -1170,32 +1170,57 @@ leppie_stash(struct monst *mtmp)
|
||||
}
|
||||
}
|
||||
|
||||
/* does monster want to avoid you? */
|
||||
staticfn boolean
|
||||
m_balks_at_approaching(struct monst *mtmp)
|
||||
/* does monster want to avoid you?
|
||||
* returns the original value of appr if not.
|
||||
* returns -1 if so.
|
||||
* returns -2 if monster wants to adhere to a particular range,
|
||||
* which may actually be further away,
|
||||
* and sets *pdistmin and *pdistmax to describe that range
|
||||
*/
|
||||
staticfn int
|
||||
m_balks_at_approaching(int oldappr, struct monst *mtmp, int *pdistmin,
|
||||
int *pdistmax)
|
||||
{
|
||||
struct obj *mwep = MON_WEP(mtmp);
|
||||
coordxy x = mtmp->mx, y = mtmp->my, ux = mtmp->mux, uy = mtmp->muy;
|
||||
int edist = dist2(x, y, ux, uy);
|
||||
const struct throw_and_return_weapon *arw;
|
||||
|
||||
if (pdistmin)
|
||||
*pdistmin = 0;
|
||||
if (pdistmax)
|
||||
*pdistmax = 0;
|
||||
|
||||
/* peaceful, far away, or can't see you */
|
||||
if (mtmp->mpeaceful
|
||||
|| (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) >= 5*5)
|
||||
|| !m_canseeu(mtmp))
|
||||
return FALSE;
|
||||
if (mtmp->mpeaceful || (edist >= 5 * 5) || !m_canseeu(mtmp))
|
||||
return oldappr;
|
||||
|
||||
/* has ammo+launcher */
|
||||
if (m_has_launcher_and_ammo(mtmp))
|
||||
return TRUE;
|
||||
return -1;
|
||||
|
||||
/* is using a polearm and in range */
|
||||
if (MON_WEP(mtmp) && is_pole(MON_WEP(mtmp))
|
||||
&& dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= MON_POLE_DIST)
|
||||
return TRUE;
|
||||
&& edist <= MON_POLE_DIST)
|
||||
return -1;
|
||||
|
||||
/* is using a throw-and-return weapon; provide min and max preferred range
|
||||
*/
|
||||
if (mwep && (arw = autoreturn_weapon(mwep)) != 0) {
|
||||
if (pdistmin)
|
||||
*pdistmin = 2 * 2;
|
||||
if (pdistmax)
|
||||
*pdistmax = arw->range * arw->range;
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* can attack from distance, and hp loss or attack not used */
|
||||
if (ranged_attk_available(mtmp)
|
||||
&& ((mtmp->mhp < (mtmp->mhpmax+1) / 3)
|
||||
|| !mtmp->mspec_used))
|
||||
return TRUE;
|
||||
return -1;
|
||||
|
||||
return FALSE;
|
||||
return oldappr; /* leaves appr unchanged */
|
||||
}
|
||||
|
||||
staticfn boolean
|
||||
@@ -1697,7 +1722,8 @@ m_move(struct monst *mtmp, int after)
|
||||
boolean better_with_displacing = FALSE;
|
||||
unsigned seenflgs;
|
||||
struct permonst *ptr;
|
||||
int chi, mmoved = MMOVE_NOTHING; /* not strictly nec.: chi >= 0 will do */
|
||||
int chi, mmoved = MMOVE_NOTHING, /* not strictly nec.: chi >= 0 will do */
|
||||
preferredrange_min = 0, preferredrange_max = 0;
|
||||
long info[9];
|
||||
long flag;
|
||||
coordxy omx = mtmp->mx, omy = mtmp->my;
|
||||
@@ -1848,8 +1874,7 @@ m_move(struct monst *mtmp, int after)
|
||||
appr = -1;
|
||||
|
||||
/* hostiles with ranged weapon or attack try to stay away */
|
||||
if (m_balks_at_approaching(mtmp))
|
||||
appr = -1;
|
||||
appr = m_balks_at_approaching(appr, mtmp, &preferredrange_min, &preferredrange_max);
|
||||
|
||||
if (!should_see && can_track(ptr)) {
|
||||
coord *cp;
|
||||
@@ -1942,7 +1967,11 @@ m_move(struct monst *mtmp, int after)
|
||||
nearer = ((ndist = dist2(nx, ny, ggx, ggy)) < nidist);
|
||||
|
||||
if ((appr == 1 && nearer) || (appr == -1 && !nearer)
|
||||
|| (!appr && !rn2(++chcnt)) || (mmoved == MMOVE_NOTHING)) {
|
||||
|| (!appr && !rn2(++chcnt))
|
||||
|| (appr == -2
|
||||
&& ((ndist <= preferredrange_min && !nearer)
|
||||
|| (ndist >= preferredrange_max && nearer)))
|
||||
|| (mmoved == MMOVE_NOTHING)) {
|
||||
nix = nx;
|
||||
niy = ny;
|
||||
nidist = ndist;
|
||||
|
||||
182
src/mthrowu.c
182
src/mthrowu.c
@@ -12,6 +12,7 @@ staticfn const char *breathwep_name(int);
|
||||
staticfn boolean drop_throw(struct obj *, boolean, coordxy, coordxy);
|
||||
staticfn boolean blocking_terrain(coordxy, coordxy);
|
||||
staticfn int m_lined_up(struct monst *, struct monst *) NONNULLARG12;
|
||||
staticfn void return_from_mtoss(struct monst *, struct obj *, boolean);
|
||||
|
||||
#define URETREATING(x, y) \
|
||||
(distmin(u.ux, u.uy, x, y) > distmin(u.ux0, u.uy0, x, y))
|
||||
@@ -558,6 +559,10 @@ m_throw(
|
||||
boolean forcehit;
|
||||
char sym = obj->oclass;
|
||||
int hitu = 0, oldumort, blindinc = 0;
|
||||
const struct throw_and_return_weapon *arw = autoreturn_weapon(obj);
|
||||
boolean tethered_weapon =
|
||||
(obj == MON_WEP(mon) && arw && arw->tethered != 0),
|
||||
return_flightpath = FALSE;
|
||||
|
||||
gb.bhitpos.x = x;
|
||||
gb.bhitpos.y = y;
|
||||
@@ -619,8 +624,30 @@ m_throw(
|
||||
* early to avoid the dagger bug, anyone who modifies this code should
|
||||
* be careful not to use either one after it's been freed.
|
||||
*/
|
||||
if (sym)
|
||||
tmp_at(DISP_FLASH, obj_to_glyph(singleobj, rn2_on_display_rng));
|
||||
if (sym) {
|
||||
if (!tethered_weapon) {
|
||||
tmp_at(DISP_FLASH, obj_to_glyph(singleobj, rn2_on_display_rng));
|
||||
} else {
|
||||
tmp_at(DISP_TETHER, obj_to_glyph(singleobj, rn2_on_display_rng));
|
||||
/*
|
||||
* Considerations for a tethered object based on in throwit()/bhit() :
|
||||
* - wall of water/lava will stop items, and triggers return.
|
||||
* - iron bars will stop items, and triggers return.
|
||||
* - pass harmlessly through shades.
|
||||
* X stops forward motion at hit monster/hero, triggers return.
|
||||
* - closed door will stop item's forward motion, triggers return.
|
||||
* - sinks stop forward motion, triggers fall, then return.
|
||||
* - object can get tangled in a web, no return (tether snaps?).
|
||||
* On return:
|
||||
* X rn2(100) chance of returning to thrower's location.
|
||||
* X if impaired and rn2(100) == 0,
|
||||
* -50/50 chance of landing on the ground.
|
||||
* -50/50 chance of hitting the thrower and causing
|
||||
* rnd(3) damage.
|
||||
*
|
||||
*/
|
||||
}
|
||||
}
|
||||
while (range-- > 0) { /* Actually the loop is always exited by break */
|
||||
singleobj->ox = gb.bhitpos.x += dx;
|
||||
singleobj->oy = gb.bhitpos.y += dy;
|
||||
@@ -730,7 +757,12 @@ m_throw(
|
||||
}
|
||||
stop_occupation();
|
||||
if (hitu) {
|
||||
(void) drop_throw(singleobj, hitu, u.ux, u.uy);
|
||||
if (!tethered_weapon) {
|
||||
(void) drop_throw(singleobj, hitu, u.ux, u.uy);
|
||||
} else {
|
||||
/* ready for return journey */
|
||||
return_flightpath = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -751,8 +783,12 @@ m_throw(
|
||||
&& (cansee(gb.bhitpos.x, gb.bhitpos.y)
|
||||
|| (gm.marcher && canseemon(gm.marcher))))
|
||||
pline("%s misses.", The(mshot_xname(singleobj)));
|
||||
|
||||
(void) drop_throw(singleobj, 0, gb.bhitpos.x, gb.bhitpos.y);
|
||||
if (!tethered_weapon) {
|
||||
(void) drop_throw(singleobj, 0, gb.bhitpos.x, gb.bhitpos.y);
|
||||
} else {
|
||||
/*ready for return journey */
|
||||
return_flightpath = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -761,7 +797,11 @@ m_throw(
|
||||
}
|
||||
tmp_at(gb.bhitpos.x, gb.bhitpos.y);
|
||||
nh_delay_output();
|
||||
tmp_at(DISP_END, 0);
|
||||
if (arw && return_flightpath)
|
||||
return_from_mtoss(mon, singleobj, tethered_weapon);
|
||||
/* mon could be DEADMONSTER now */
|
||||
else
|
||||
tmp_at(DISP_END, 0);
|
||||
gm.mesg_given = 0; /* reset */
|
||||
|
||||
if (blindinc) {
|
||||
@@ -777,6 +817,121 @@ m_throw(
|
||||
|
||||
#undef MT_FLIGHTCHECK
|
||||
|
||||
staticfn void
|
||||
return_from_mtoss(struct monst *magr, struct obj *otmp, boolean tethered_weapon)
|
||||
{
|
||||
boolean impaired = (magr->mconf || magr->mstun || magr->mblinded),
|
||||
notcaught = FALSE, hits_thrower = FALSE;
|
||||
coordxy x = gb.bhitpos.x, y = gb.bhitpos.y;
|
||||
int made_it_back = rn2(100), dmg = 0;
|
||||
|
||||
if (otmp && made_it_back) {
|
||||
/* it made it back to thrower's location */
|
||||
if (tethered_weapon) {
|
||||
tmp_at(DISP_END, BACKTRACK);
|
||||
} else {
|
||||
int dx = sgn(x - magr->mx),
|
||||
dy = sgn(y - magr->my);
|
||||
|
||||
if (x != magr->mx || y != magr->my) {
|
||||
tmp_at(DISP_FLASH, obj_to_glyph(otmp, rn2_on_display_rng));
|
||||
while (isok(x, y) && (x != magr->mx || y != magr->my)) {
|
||||
tmp_at(x, y);
|
||||
nh_delay_output();
|
||||
x -= dx;
|
||||
y -= dy;
|
||||
}
|
||||
tmp_at(DISP_END, 0);
|
||||
}
|
||||
}
|
||||
x = magr->mx;
|
||||
y = magr->my;
|
||||
if (!impaired && rn2(100)) {
|
||||
static long do_not_annoy = 0;
|
||||
|
||||
if (!do_not_annoy || (svm.moves - do_not_annoy) > 500) {
|
||||
pline("%s to %s %s!", Tobjnam(otmp, "return"),
|
||||
s_suffix(mon_nam(magr)), mbodypart(magr, HAND));
|
||||
do_not_annoy = svm.moves;
|
||||
}
|
||||
if (otmp) {
|
||||
add_to_minv(magr, otmp);
|
||||
if (tethered_weapon) {
|
||||
magr->mw = otmp;
|
||||
otmp->owornmask |= W_WEP;
|
||||
}
|
||||
}
|
||||
if (cansee(x, y))
|
||||
newsym(x, y);
|
||||
} else {
|
||||
boolean mlevitating = FALSE; /* msg future-proofing only */
|
||||
|
||||
dmg = rn2(2);
|
||||
if (!dmg) {
|
||||
if (!Blind) {
|
||||
pline("%s back to %s, landing %s %s %s.",
|
||||
Tobjnam(otmp, "return"), mon_nam(magr),
|
||||
mlevitating ? "beneath" : "at", mhis(magr),
|
||||
makeplural(mbodypart(magr, FOOT)));
|
||||
} else if (!Deaf) {
|
||||
You_hear("%s land near %s.", Something, mon_nam(magr));
|
||||
}
|
||||
} else {
|
||||
dmg += rnd(3);
|
||||
if (!Blind) {
|
||||
pline("%s back toward %s, hitting %s %s!",
|
||||
Tobjnam(otmp, "fly"),
|
||||
mon_nam(magr),
|
||||
mhis(magr),
|
||||
body_part(ARM));
|
||||
} else if (!Deaf) {
|
||||
You_hear("%s hit %s with a thud!", something,
|
||||
mon_nam(magr));
|
||||
}
|
||||
hits_thrower = TRUE;
|
||||
}
|
||||
notcaught = TRUE;
|
||||
}
|
||||
} else {
|
||||
/* it didn't make it back to thrower's location */
|
||||
if (tethered_weapon)
|
||||
tmp_at(DISP_END, 0);
|
||||
You_hear("a loud snap!");
|
||||
notcaught = TRUE;
|
||||
}
|
||||
if (otmp) {
|
||||
if (hits_thrower) {
|
||||
if (otmp->oartifact)
|
||||
(void) artifact_hit((struct monst *) 0, magr, otmp, &dmg, 0);
|
||||
magr->mhp -= dmg;
|
||||
/* magr could be a DEADMONSTER now */
|
||||
}
|
||||
if (notcaught) {
|
||||
(void) snuff_candle(otmp);
|
||||
if (!ship_object(otmp, x, y, FALSE)) {
|
||||
if (flooreffects(otmp, x, y, "drop")) {
|
||||
if (cansee(x, y))
|
||||
newsym(x, y);
|
||||
return;
|
||||
}
|
||||
place_object(otmp, x, y);
|
||||
stackobj(otmp);
|
||||
}
|
||||
if (!Deaf && !Underwater) {
|
||||
/* Some sound effects when item lands in water or lava */
|
||||
if (is_pool(x, y) || (is_lava(x, y) && !is_flammable(otmp))) {
|
||||
Soundeffect(se_splash, 50);
|
||||
pline((weight(otmp) > 9) ? "Splash!" : "Plop!");
|
||||
}
|
||||
}
|
||||
if (obj_sheds_light(otmp))
|
||||
gv.vision_full_recalc = 1;
|
||||
}
|
||||
}
|
||||
if (cansee(x, y))
|
||||
newsym(x, y);
|
||||
}
|
||||
|
||||
/* Monster throws item at another monster */
|
||||
int
|
||||
thrwmm(struct monst *mtmp, struct monst *mtarg)
|
||||
@@ -988,6 +1143,9 @@ thrwmu(struct monst *mtmp)
|
||||
struct obj *otmp, *mwep;
|
||||
coordxy x, y;
|
||||
const char *onm;
|
||||
int rang;
|
||||
const struct throw_and_return_weapon *arw;
|
||||
boolean always_toss = FALSE;
|
||||
|
||||
/* Rearranged beginning so monsters can use polearms not in a line */
|
||||
if (mtmp->weapon_check == NEED_WEAPON || !MON_WEP(mtmp)) {
|
||||
@@ -1003,10 +1161,10 @@ thrwmu(struct monst *mtmp)
|
||||
return;
|
||||
|
||||
if (is_pole(otmp)) {
|
||||
int dam, hitv, rang;
|
||||
int dam, hitv;
|
||||
|
||||
if (otmp != MON_WEP(mtmp))
|
||||
return; /* polearm must be wielded */
|
||||
return; /* polearm, aklys must be wielded */
|
||||
|
||||
/*
|
||||
* MON_POLE_DIST encompasses knight's move range (5): two spots
|
||||
@@ -1047,6 +1205,11 @@ thrwmu(struct monst *mtmp)
|
||||
(void) thitu(hitv, dam, &otmp, (char *) 0);
|
||||
stop_occupation();
|
||||
return;
|
||||
} else if ((arw = autoreturn_weapon(otmp)) != 0 && !mwelded(otmp)) {
|
||||
rang = dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy);
|
||||
if (rang > arw->range || !couldsee(mtmp->mx, mtmp->my))
|
||||
return; /* Out of range, or intervening wall */
|
||||
always_toss = TRUE;
|
||||
}
|
||||
|
||||
x = mtmp->mx;
|
||||
@@ -1058,7 +1221,8 @@ thrwmu(struct monst *mtmp)
|
||||
*/
|
||||
if (!lined_up(mtmp)
|
||||
|| (URETREATING(x, y)
|
||||
&& rn2(BOLT_LIM - distmin(x, y, mtmp->mux, mtmp->muy))))
|
||||
&& (!always_toss
|
||||
&& rn2(BOLT_LIM - distmin(x, y, mtmp->mux, mtmp->muy)))))
|
||||
return;
|
||||
|
||||
mwep = MON_WEP(mtmp); /* wielded weapon */
|
||||
|
||||
52
src/weapon.c
52
src/weapon.c
@@ -493,21 +493,38 @@ oselect(struct monst *mtmp, int type)
|
||||
return (struct obj *) 0;
|
||||
}
|
||||
|
||||
/* TODO: have monsters use aklys' throw-and-return */
|
||||
static NEARDATA const int rwep[] = {
|
||||
DWARVISH_SPEAR, SILVER_SPEAR, ELVEN_SPEAR, SPEAR, ORCISH_SPEAR, JAVELIN,
|
||||
SHURIKEN, YA, SILVER_ARROW, ELVEN_ARROW, ARROW, ORCISH_ARROW,
|
||||
CROSSBOW_BOLT, SILVER_DAGGER, ELVEN_DAGGER, DAGGER, ORCISH_DAGGER, KNIFE,
|
||||
FLINT, ROCK, LOADSTONE, LUCKSTONE, DART,
|
||||
/* BOOMERANG, */ CREAM_PIE
|
||||
FLINT, ROCK, LOADSTONE, LUCKSTONE, DART, CREAM_PIE,
|
||||
};
|
||||
|
||||
/* polearms */
|
||||
static NEARDATA const int pwep[] = { HALBERD, BARDICHE, SPETUM,
|
||||
BILL_GUISARME, VOULGE, RANSEUR,
|
||||
GUISARME, GLAIVE, LUCERN_HAMMER,
|
||||
BEC_DE_CORBIN, FAUCHARD, PARTISAN,
|
||||
LANCE };
|
||||
|
||||
/* throw-and-return weapons */
|
||||
static NEARDATA const struct throw_and_return_weapon arwep[] = {
|
||||
/* { BOOMERANG, 5, 0 }, */
|
||||
{ AKLYS, (BOLT_LIM / 2), 1 },
|
||||
};
|
||||
|
||||
const struct throw_and_return_weapon *
|
||||
autoreturn_weapon(struct obj *otmp)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SIZE(arwep); i++) {
|
||||
if (otmp->otyp == arwep[i].otyp)
|
||||
return &arwep[i];
|
||||
}
|
||||
return (struct throw_and_return_weapon *) 0;
|
||||
}
|
||||
|
||||
/* select a ranged weapon for the monster */
|
||||
struct obj *
|
||||
select_rwep(struct monst *mtmp)
|
||||
@@ -557,9 +574,31 @@ select_rwep(struct monst *mtmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Next, try to select a throw-and-return weapon, since they are
|
||||
* also not as expendable. Again, don't pick one if monster's
|
||||
* weapon is welded.
|
||||
*/
|
||||
for (i = 0; i < SIZE(arwep); i++) {
|
||||
const struct throw_and_return_weapon *arw = &arwep[i];
|
||||
|
||||
if (!mindless(mtmp->data) && !is_animal(mtmp->data) && !mweponly
|
||||
&& dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= arw->range
|
||||
&& couldsee(mtmp->mx, mtmp->my)) {
|
||||
if ((((mtmp->misc_worn_check & W_ARMS) == 0)
|
||||
|| !objects[arw->otyp].oc_bimanual)
|
||||
&& (objects[arw->otyp].oc_material != SILVER
|
||||
|| !mon_hates_silver(mtmp))) {
|
||||
if ((otmp = oselect(mtmp, arw->otyp)) != 0
|
||||
&& (otmp == mwep || !mweponly)) {
|
||||
gp.propellor = otmp; /* force the monster to wield it */
|
||||
return otmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* other than these two specific cases, always select the
|
||||
* other than the specific cases above, always select the
|
||||
* most potent ranged weapon to hand.
|
||||
*/
|
||||
for (i = 0; i < SIZE(rwep); i++) {
|
||||
@@ -840,10 +879,15 @@ mon_wield_item(struct monst *mon)
|
||||
mon->weapon_check = NEED_WEAPON;
|
||||
if (canseemon(mon)) {
|
||||
boolean newly_welded;
|
||||
const struct throw_and_return_weapon *arw;
|
||||
|
||||
pline_mon(mon, "%s wields %s%c",
|
||||
Monnam(mon), doname(obj),
|
||||
exclaim ? '!' : '.');
|
||||
if ((arw = autoreturn_weapon(obj)) != 0 && arw->tethered != 0)
|
||||
pline_mon(mon, "%s secures the tether on %s.", Monnam(mon),
|
||||
the(xname(obj)));
|
||||
|
||||
/* 3.6.3: mwelded() predicate expects the object to have its
|
||||
W_WEP bit set in owormmask, but the pline here and for
|
||||
artifact_light don't want that because they'd have '(weapon
|
||||
|
||||
Reference in New Issue
Block a user