/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* hack.fight.c - version 1.0.3 */
extern struct permonst li_dog
, dog
, la_dog
;
extern char *exclam(), *xname();
extern struct obj
*mkobj_at();
static boolean far_noise
;
/* hitmm returns 0 (miss), 1 (hit), or 2 (kill) */
hitmm(magr
,mdef
) register struct monst
*magr
,*mdef
; {
register struct permonst
*pa
= magr
->data
, *pd
= mdef
->data
;
if(index("Eauy", pa
->mlet
)) return(0);
if(magr
->mfroz
) return(0); /* riv05!a3 */
tmp
= pd
->ac
+ pa
->mlevel
;
if(mdef
->mconf
|| mdef
->mfroz
|| mdef
->msleep
){
if(mdef
->msleep
) mdef
->msleep
= 0;
if(hit
) mdef
->msleep
= 0;
vis
= (cansee(magr
->mx
,magr
->my
) && cansee(mdef
->mx
,mdef
->my
));
if(mdef
->mimic
) seemimic(mdef
);
if(magr
->mimic
) seemimic(magr
);
(void) sprintf(buf
,"%s %s", Monnam(magr
),
hit
? "hits" : "misses");
pline("%s %s.", buf
, monnam(mdef
));
boolean far
= (dist(magr
->mx
, magr
->my
) > 15);
if(far
!= far_noise
|| moves
-noisetime
> 10) {
pline("You hear some noises%s.",
far
? " in the distance" : "");
if(magr
->data
->mlet
== 'c' && !magr
->cham
) {
if(vis
) pline("%s is turned to stone!", Monnam(mdef
));
pline("You have a peculiarly sad feeling for a moment, then it passes.");
if((mdef
->mhp
-= d(pa
->damn
,pa
->damd
)) < 1) {
magr
->mhpmax
+= 1 + rn2(pd
->mlevel
+1);
if(magr
->mtame
&& magr
->mhpmax
> 8*pa
->mlevel
){
if(pa
== &li_dog
) magr
->data
= pa
= &dog
;
else if(pa
== &dog
) magr
->data
= pa
= &la_dog
;
if(vis
) pline("%s is killed!", Monnam(mdef
));
pline("You have a sad feeling for a moment, then it passes.");
/* drop (perhaps) a cadaver and remove monster */
mondied(mdef
) register struct monst
*mdef
; {
register struct permonst
*pd
= mdef
->data
;
if(letter(pd
->mlet
) && rn2(3)){
(void) mkobj_at(pd
->mlet
,mdef
->mx
,mdef
->my
);
if(cansee(mdef
->mx
,mdef
->my
)){
atl(mdef
->mx
,mdef
->my
,fobj
->olet
);
/* drop a rock and remove monster */
monstone(mdef
) register struct monst
*mdef
; {
if(index(mlarge
, mdef
->data
->mlet
))
mksobj_at(ENORMOUS_ROCK
, mdef
->mx
, mdef
->my
);
mksobj_at(ROCK
, mdef
->mx
, mdef
->my
);
if(cansee(mdef
->mx
, mdef
->my
)){
atl(mdef
->mx
,mdef
->my
,fobj
->olet
);
fightm(mtmp
) register struct monst
*mtmp
; {
register struct monst
*mon
;
for(mon
= fmon
; mon
; mon
= mon
->nmon
) if(mon
!= mtmp
) {
if(DIST(mon
->mx
,mon
->my
,mtmp
->mx
,mtmp
->my
) < 3)
/* u is hit by sth, but not a monster */
if(u
.uac
+ tlev
<= rnd(20)) {
if(Blind
) pline("It misses.");
else pline("You are almost hit by %s!", buf
);
if(Blind
) pline("You are hit!");
else pline("You are hit by %s!", buf
);
char mlarge
[] = "bCDdegIlmnoPSsTUwY',&";
hmon(mon
,obj
,thrown
) /* return TRUE if mon still alive */
register struct monst
*mon
;
register struct obj
*obj
;
tmp
= rnd(2); /* attack with bare hands */
if(mon
->data
->mlet
== 'c' && !uarmg
){
pline("You hit the cockatrice with your bare hands.");
pline("You turn to stone ...");
} else if(obj
->olet
== WEAPON_SYM
|| obj
->otyp
== PICK_AXE
) {
if(obj
== uwep
&& (obj
->otyp
> SPEAR
|| obj
->otyp
< BOOMERANG
))
if(index(mlarge
, mon
->data
->mlet
)) {
tmp
= rnd(objects
[obj
->otyp
].wldam
);
if(obj
->otyp
== TWO_HANDED_SWORD
) tmp
+= d(2,6);
else if(obj
->otyp
== FLAIL
) tmp
+= rnd(4);
tmp
= rnd(objects
[obj
->otyp
].wsdam
);
if(!thrown
&& obj
== uwep
&& obj
->otyp
== BOOMERANG
pline("As you hit %s, the boomerang breaks into splinters.",
setworn((struct obj
*) 0, obj
->owornmask
);
obfree(obj
, (struct obj
*) 0);
if(mon
->data
->mlet
== 'O' && obj
->otyp
== TWO_HANDED_SWORD
&&
!strcmp(ONAME(obj
), "Orcrist"))
} else switch(obj
->otyp
) {
pline("You succeed in destroying your camera. Congratulations!");
setworn((struct obj
*) 0, obj
->owornmask
);
obfree(obj
, (struct obj
*) 0);
pline("You hit %s with the cockatrice corpse.",
if(mon
->data
->mlet
== 'c') {
pline("%s is turned to stone!", Monnam(mon
));
case CLOVE_OF_GARLIC
: /* no effect against demons */
if(index(UNDEAD
, mon
->data
->mlet
))
/* non-weapons can damage because of their weight */
/****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG) */
tmp
+= u
.udaminc
+ dbon();
if((tmp
-= u
.uswldtim
) <= 0) {
pline("Your arms are no longer able to hit.");
if(mon
->mtame
&& (!mon
->mflee
|| mon
->mfleetim
)) {
mon
->mflee
= 1; /* Rick Richardson */
mon
->mfleetim
+= 10*rnd(tmp
);
/* this assumes that we cannot throw plural things */
hit( xname(obj
) /* or: objects[obj->otyp].oc_name */,
pline("You hit %s%s", monnam(mon
), exclam(tmp
));
if(u
.umconf
&& !thrown
) {
pline("Your hands stop glowing blue.");
if(!mon
->mfroz
&& !mon
->msleep
)
pline("%s appears confused.",Monnam(mon
));
return(TRUE
); /* mon still alive */
/* try to attack; return FALSE if monster evaded */
/* u.dx and u.dy must be set */
register struct monst
*mtmp
;
register struct permonst
*mdat
;
u_wipe_engr(3); /* andrew@orca: prevent unlimited pick-axe attacks */
if(mdat
->mlet
== 'L' && !mtmp
->mfroz
&& !mtmp
->msleep
&&
!mtmp
->mconf
&& mtmp
->mcansee
&& !rn2(7) &&
(m_move(mtmp
, 0) == 2 /* he died */ || /* he moved: */
mtmp
->mx
!= u
.ux
+u
.dx
|| mtmp
->my
!= u
.uy
+u
.dy
))
if(!u
.ustuck
&& !mtmp
->mflee
) u
.ustuck
= mtmp
;
switch(levl
[u
.ux
+u
.dx
][u
.uy
+u
.dy
].scrsym
){
pline("The door actually was a Mimic.");
pline("The chest was a Mimic!");
pline("Wait! That's a Mimic!");
wakeup(mtmp
); /* clears mtmp->mimic */
if(mtmp
->mhide
&& mtmp
->mundetected
){
register struct obj
*obj
;
if((obj
= o_at(mtmp
->mx
,mtmp
->my
)) && !Blind
)
pline("Wait! There's a %s hiding under %s!",
mdat
->mname
, doname(obj
));
tmp
= u
.uluck
+ u
.ulevel
+ mdat
->ac
+ abon();
if(uwep
->olet
== WEAPON_SYM
|| uwep
->otyp
== PICK_AXE
)
if(uwep
->otyp
== TWO_HANDED_SWORD
) tmp
-= 1;
else if(uwep
->otyp
== DAGGER
) tmp
+= 2;
else if(uwep
->otyp
== CRYSKNIFE
) tmp
+= 3;
else if(uwep
->otyp
== SPEAR
&&
index("XDne", mdat
->mlet
)) tmp
+= 2;
if(!rn2(10)) mtmp
->mfroz
= 0;
if(mtmp
->mflee
) tmp
+= 2;
/* with a lot of luggage, your agility diminishes */
tmp
-= (inv_weight() + 40)/20;
if(tmp
<= rnd(20) && !u
.uswallow
){
if(Blind
) pline("You miss it.");
else pline("You miss %s.",monnam(mtmp
));
/* we hit the monster; be careful: it might die! */
if((malive
= hmon(mtmp
,uwep
,0)) == TRUE
) {
/* monster still alive */
if(!rn2(25) && mtmp
->mhp
< mtmp
->mhpmax
/2) {
if(!rn2(3)) mtmp
->mfleetim
= rnd(100);
if(u
.ustuck
== mtmp
&& !u
.uswallow
)
cutworm(mtmp
, u
.ux
+u
.dx
, u
.uy
+u
.dy
,
pline("You are splashed by the blob's acid!");
if(!rn2(30)) corrode_armor();
if(!rn2(6)) corrode_weapon();
if(malive
&& mdat
->mlet
== 'E' && canseemon(mtmp
)
&& !mtmp
->mcan
&& rn2(3)) {
pline("You are frozen by the floating eye's gaze!");
nomul((u
.ulevel
> 6 || rn2(4)) ? rn1(20,-21) : -200);
pline("The blinded floating eye cannot defend itself.");
if(!rn2(500)) if((int)u
.uluck
> LUCKMIN
) u
.uluck
--;