]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - hack/hack.fight.c
2 * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
6 static char rcsid
[] = "$NetBSD: hack.fight.c,v 1.3 1995/03/23 08:30:12 cgd Exp $";
10 extern struct permonst li_dog
, dog
, la_dog
;
11 extern char *exclam(), *xname();
12 extern struct obj
*mkobj_at();
14 static boolean far_noise
;
15 static long noisetime
;
17 /* hitmm returns 0 (miss), 1 (hit), or 2 (kill) */
18 hitmm(magr
,mdef
) register struct monst
*magr
,*mdef
; {
19 register struct permonst
*pa
= magr
->data
, *pd
= mdef
->data
;
23 if(index("Eauy", pa
->mlet
)) return(0);
24 if(magr
->mfroz
) return(0); /* riv05!a3 */
25 tmp
= pd
->ac
+ pa
->mlevel
;
26 if(mdef
->mconf
|| mdef
->mfroz
|| mdef
->msleep
){
28 if(mdef
->msleep
) mdef
->msleep
= 0;
30 hit
= (tmp
> rnd(20));
31 if(hit
) mdef
->msleep
= 0;
32 vis
= (cansee(magr
->mx
,magr
->my
) && cansee(mdef
->mx
,mdef
->my
));
35 if(mdef
->mimic
) seemimic(mdef
);
36 if(magr
->mimic
) seemimic(magr
);
37 (void) sprintf(buf
,"%s %s", Monnam(magr
),
38 hit
? "hits" : "misses");
39 pline("%s %s.", buf
, monnam(mdef
));
41 boolean far
= (dist(magr
->mx
, magr
->my
) > 15);
42 if(far
!= far_noise
|| moves
-noisetime
> 10) {
45 pline("You hear some noises%s.",
46 far
? " in the distance" : "");
50 if(magr
->data
->mlet
== 'c' && !magr
->cham
) {
52 if(vis
) pline("%s is turned to stone!", Monnam(mdef
));
54 pline("You have a peculiarly sad feeling for a moment, then it passes.");
58 if((mdef
->mhp
-= d(pa
->damn
,pa
->damd
)) < 1) {
59 magr
->mhpmax
+= 1 + rn2(pd
->mlevel
+1);
60 if(magr
->mtame
&& magr
->mhpmax
> 8*pa
->mlevel
){
61 if(pa
== &li_dog
) magr
->data
= pa
= &dog
;
62 else if(pa
== &dog
) magr
->data
= pa
= &la_dog
;
64 if(vis
) pline("%s is killed!", Monnam(mdef
));
66 pline("You have a sad feeling for a moment, then it passes.");
74 /* drop (perhaps) a cadaver and remove monster */
75 mondied(mdef
) register struct monst
*mdef
; {
76 register struct permonst
*pd
= mdef
->data
;
77 if(letter(pd
->mlet
) && rn2(3)){
78 (void) mkobj_at(pd
->mlet
,mdef
->mx
,mdef
->my
);
79 if(cansee(mdef
->mx
,mdef
->my
)){
81 atl(mdef
->mx
,mdef
->my
,fobj
->olet
);
88 /* drop a rock and remove monster */
89 monstone(mdef
) register struct monst
*mdef
; {
91 if(index(mlarge
, mdef
->data
->mlet
))
92 mksobj_at(ENORMOUS_ROCK
, mdef
->mx
, mdef
->my
);
94 mksobj_at(ROCK
, mdef
->mx
, mdef
->my
);
95 if(cansee(mdef
->mx
, mdef
->my
)){
97 atl(mdef
->mx
,mdef
->my
,fobj
->olet
);
103 fightm(mtmp
) register struct monst
*mtmp
; {
104 register struct monst
*mon
;
105 for(mon
= fmon
; mon
; mon
= mon
->nmon
) if(mon
!= mtmp
) {
106 if(DIST(mon
->mx
,mon
->my
,mtmp
->mx
,mtmp
->my
) < 3)
108 return(hitmm(mtmp
,mon
));
113 /* u is hit by sth, but not a monster */
120 if(u
.uac
+ tlev
<= rnd(20)) {
121 if(Blind
) pline("It misses.");
122 else pline("You are almost hit by %s!", buf
);
125 if(Blind
) pline("You are hit!");
126 else pline("You are hit by %s!", buf
);
132 char mlarge
[] = "bCDdegIlmnoPSsTUwY',&";
135 hmon(mon
,obj
,thrown
) /* return TRUE if mon still alive */
136 register struct monst
*mon
;
137 register struct obj
*obj
;
141 boolean hittxt
= FALSE
;
144 tmp
= rnd(2); /* attack with bare hands */
145 if(mon
->data
->mlet
== 'c' && !uarmg
){
146 pline("You hit the cockatrice with your bare hands.");
147 pline("You turn to stone ...");
150 } else if(obj
->olet
== WEAPON_SYM
|| obj
->otyp
== PICK_AXE
) {
151 if(obj
== uwep
&& (obj
->otyp
> SPEAR
|| obj
->otyp
< BOOMERANG
))
154 if(index(mlarge
, mon
->data
->mlet
)) {
155 tmp
= rnd(objects
[obj
->otyp
].wldam
);
156 if(obj
->otyp
== TWO_HANDED_SWORD
) tmp
+= d(2,6);
157 else if(obj
->otyp
== FLAIL
) tmp
+= rnd(4);
159 tmp
= rnd(objects
[obj
->otyp
].wsdam
);
162 if(!thrown
&& obj
== uwep
&& obj
->otyp
== BOOMERANG
164 pline("As you hit %s, the boomerang breaks into splinters.",
167 setworn((struct obj
*) 0, obj
->owornmask
);
168 obfree(obj
, (struct obj
*) 0);
172 if(mon
->data
->mlet
== 'O' && obj
->otyp
== TWO_HANDED_SWORD
&&
173 !strcmp(ONAME(obj
), "Orcrist"))
175 } else switch(obj
->otyp
) {
176 case HEAVY_IRON_BALL
:
177 tmp
= rnd(25); break;
178 case EXPENSIVE_CAMERA
:
179 pline("You succeed in destroying your camera. Congratulations!");
182 setworn((struct obj
*) 0, obj
->owornmask
);
183 obfree(obj
, (struct obj
*) 0);
185 case DEAD_COCKATRICE
:
186 pline("You hit %s with the cockatrice corpse.",
188 if(mon
->data
->mlet
== 'c') {
193 pline("%s is turned to stone!", Monnam(mon
));
196 case CLOVE_OF_GARLIC
: /* no effect against demons */
197 if(index(UNDEAD
, mon
->data
->mlet
))
202 /* non-weapons can damage because of their weight */
203 /* (but not too much) */
210 /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG) */
212 tmp
+= u
.udaminc
+ dbon();
214 if((tmp
-= u
.uswldtim
) <= 0) {
215 pline("Your arms are no longer able to hit.");
225 if(mon
->mtame
&& (!mon
->mflee
|| mon
->mfleetim
)) {
226 mon
->mflee
= 1; /* Rick Richardson */
227 mon
->mfleetim
+= 10*rnd(tmp
);
232 /* this assumes that we cannot throw plural things */
233 hit( xname(obj
) /* or: objects[obj->otyp].oc_name */,
236 pline("You hit it.");
238 pline("You hit %s%s", monnam(mon
), exclam(tmp
));
241 if(u
.umconf
&& !thrown
) {
243 pline("Your hands stop glowing blue.");
244 if(!mon
->mfroz
&& !mon
->msleep
)
245 pline("%s appears confused.",Monnam(mon
));
250 return(TRUE
); /* mon still alive */
253 /* try to attack; return FALSE if monster evaded */
254 /* u.dx and u.dy must be set */
256 register struct monst
*mtmp
;
259 boolean malive
= TRUE
;
260 register struct permonst
*mdat
;
263 u_wipe_engr(3); /* andrew@orca: prevent unlimited pick-axe attacks */
265 if(mdat
->mlet
== 'L' && !mtmp
->mfroz
&& !mtmp
->msleep
&&
266 !mtmp
->mconf
&& mtmp
->mcansee
&& !rn2(7) &&
267 (m_move(mtmp
, 0) == 2 /* he died */ || /* he moved: */
268 mtmp
->mx
!= u
.ux
+u
.dx
|| mtmp
->my
!= u
.uy
+u
.dy
))
272 if(!u
.ustuck
&& !mtmp
->mflee
) u
.ustuck
= mtmp
;
273 switch(levl
[u
.ux
+u
.dx
][u
.uy
+u
.dy
].scrsym
){
275 pline("The door actually was a Mimic.");
278 pline("The chest was a Mimic!");
281 pline("Wait! That's a Mimic!");
283 wakeup(mtmp
); /* clears mtmp->mimic */
289 if(mtmp
->mhide
&& mtmp
->mundetected
){
290 register struct obj
*obj
;
292 mtmp
->mundetected
= 0;
293 if((obj
= o_at(mtmp
->mx
,mtmp
->my
)) && !Blind
)
294 pline("Wait! There's a %s hiding under %s!",
295 mdat
->mname
, doname(obj
));
299 tmp
= u
.uluck
+ u
.ulevel
+ mdat
->ac
+ abon();
301 if(uwep
->olet
== WEAPON_SYM
|| uwep
->otyp
== PICK_AXE
)
303 if(uwep
->otyp
== TWO_HANDED_SWORD
) tmp
-= 1;
304 else if(uwep
->otyp
== DAGGER
) tmp
+= 2;
305 else if(uwep
->otyp
== CRYSKNIFE
) tmp
+= 3;
306 else if(uwep
->otyp
== SPEAR
&&
307 index("XDne", mdat
->mlet
)) tmp
+= 2;
315 if(!rn2(10)) mtmp
->mfroz
= 0;
317 if(mtmp
->mflee
) tmp
+= 2;
318 if(u
.utrap
) tmp
-= 3;
320 /* with a lot of luggage, your agility diminishes */
321 tmp
-= (inv_weight() + 40)/20;
323 if(tmp
<= rnd(20) && !u
.uswallow
){
324 if(Blind
) pline("You miss it.");
325 else pline("You miss %s.",monnam(mtmp
));
327 /* we hit the monster; be careful: it might die! */
329 if((malive
= hmon(mtmp
,uwep
,0)) == TRUE
) {
330 /* monster still alive */
331 if(!rn2(25) && mtmp
->mhp
< mtmp
->mhpmax
/2) {
333 if(!rn2(3)) mtmp
->mfleetim
= rnd(100);
334 if(u
.ustuck
== mtmp
&& !u
.uswallow
)
339 cutworm(mtmp
, u
.ux
+u
.dx
, u
.uy
+u
.dy
,
340 uwep
? uwep
->otyp
: 0);
343 if(mdat
->mlet
== 'a') {
345 pline("You are splashed by the blob's acid!");
346 losehp_m(rnd(6), mtmp
);
347 if(!rn2(30)) corrode_armor();
349 if(!rn2(6)) corrode_weapon();
352 if(malive
&& mdat
->mlet
== 'E' && canseemon(mtmp
)
353 && !mtmp
->mcan
&& rn2(3)) {
355 pline("You are frozen by the floating eye's gaze!");
356 nomul((u
.ulevel
> 6 || rn2(4)) ? rn1(20,-21) : -200);
358 pline("The blinded floating eye cannot defend itself.");
359 if(!rn2(500)) if((int)u
.uluck
> LUCKMIN
) u
.uluck
--;