1*4318c66eSSascha Wildner /* @(#)com7.c 8.2 (Berkeley) 4/28/95 */
2*4318c66eSSascha Wildner /* $NetBSD: command7.c,v 1.4 2018/02/04 08:48:05 mrg Exp $ */
3*4318c66eSSascha Wildner
4*4318c66eSSascha Wildner /*
5937f07e0SSascha Wildner * Copyright (c) 1983, 1993
6937f07e0SSascha Wildner * The Regents of the University of California. All rights reserved.
7937f07e0SSascha Wildner *
8937f07e0SSascha Wildner * Redistribution and use in source and binary forms, with or without
9937f07e0SSascha Wildner * modification, are permitted provided that the following conditions
10937f07e0SSascha Wildner * are met:
11937f07e0SSascha Wildner * 1. Redistributions of source code must retain the above copyright
12937f07e0SSascha Wildner * notice, this list of conditions and the following disclaimer.
13937f07e0SSascha Wildner * 2. Redistributions in binary form must reproduce the above copyright
14937f07e0SSascha Wildner * notice, this list of conditions and the following disclaimer in the
15937f07e0SSascha Wildner * documentation and/or other materials provided with the distribution.
16937f07e0SSascha Wildner * 3. Neither the name of the University nor the names of its contributors
17937f07e0SSascha Wildner * may be used to endorse or promote products derived from this software
18937f07e0SSascha Wildner * without specific prior written permission.
19937f07e0SSascha Wildner *
20937f07e0SSascha Wildner * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21937f07e0SSascha Wildner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22937f07e0SSascha Wildner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23937f07e0SSascha Wildner * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24937f07e0SSascha Wildner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25937f07e0SSascha Wildner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26937f07e0SSascha Wildner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27937f07e0SSascha Wildner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28937f07e0SSascha Wildner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29937f07e0SSascha Wildner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30937f07e0SSascha Wildner * SUCH DAMAGE.
31937f07e0SSascha Wildner */
32937f07e0SSascha Wildner
33*4318c66eSSascha Wildner #include "extern.h"
34937f07e0SSascha Wildner
35937f07e0SSascha Wildner int
fight(int enemy,int strength)36937f07e0SSascha Wildner fight(int enemy, int strength)
37937f07e0SSascha Wildner {
38*4318c66eSSascha Wildner int lifeline = 0;
39937f07e0SSascha Wildner int hurt;
40937f07e0SSascha Wildner char auxbuf[LINELENGTH];
41937f07e0SSascha Wildner char *next;
42937f07e0SSascha Wildner int i;
43937f07e0SSascha Wildner int exhaustion;
44937f07e0SSascha Wildner
45*4318c66eSSascha Wildner exhaustion = 0;
46937f07e0SSascha Wildner fighton:
47*4318c66eSSascha Wildner ourtime++;
48937f07e0SSascha Wildner snooze -= 5;
49*4318c66eSSascha Wildner if (snooze > ourtime)
50*4318c66eSSascha Wildner exhaustion = CYCLE / (snooze - ourtime);
51937f07e0SSascha Wildner else {
52937f07e0SSascha Wildner puts("You collapse exhausted, and he pulverizes your skull.");
53*4318c66eSSascha Wildner die();
54937f07e0SSascha Wildner }
55*4318c66eSSascha Wildner if (snooze - ourtime < 20)
56937f07e0SSascha Wildner puts("You look tired! I hope you're able to fight.");
57937f07e0SSascha Wildner next = getcom(auxbuf, LINELENGTH, "<fight!>-: ", 0);
58937f07e0SSascha Wildner for (i = 0; next && i < 10; i++)
59937f07e0SSascha Wildner next = getword(next, words[i], -1);
60937f07e0SSascha Wildner parse();
61937f07e0SSascha Wildner switch (wordvalue[wordnumber]) {
62*4318c66eSSascha Wildner
63937f07e0SSascha Wildner case KILL:
64937f07e0SSascha Wildner case SMITE:
65937f07e0SSascha Wildner if (testbit(inven, TWO_HANDED))
66937f07e0SSascha Wildner hurt = rnd(70) - 2 * card(injuries, NUMOFINJURIES) -
67937f07e0SSascha Wildner ucard(wear) - exhaustion;
68937f07e0SSascha Wildner else if (testbit(inven, SWORD) || testbit(inven, BROAD))
69937f07e0SSascha Wildner hurt = rnd(50) % (WEIGHT - carrying) -
70937f07e0SSascha Wildner card(injuries, NUMOFINJURIES) - encumber -
71937f07e0SSascha Wildner exhaustion;
72937f07e0SSascha Wildner else if (testbit(inven, KNIFE) || testbit(inven, MALLET) ||
73937f07e0SSascha Wildner testbit(inven, CHAIN) || testbit(inven, MACE) ||
74937f07e0SSascha Wildner testbit(inven, HALBERD))
75937f07e0SSascha Wildner hurt = rnd(15) - card(injuries, NUMOFINJURIES) -
76937f07e0SSascha Wildner exhaustion;
77937f07e0SSascha Wildner else
78937f07e0SSascha Wildner hurt = rnd(7) - encumber;
79937f07e0SSascha Wildner if (hurt < 5)
80937f07e0SSascha Wildner switch (rnd(3)) {
81*4318c66eSSascha Wildner
82937f07e0SSascha Wildner case 0:
83937f07e0SSascha Wildner puts("You swung wide and missed.");
84937f07e0SSascha Wildner break;
85937f07e0SSascha Wildner case 1:
86937f07e0SSascha Wildner puts("He checked your blow. CLASH! CLANG!");
87937f07e0SSascha Wildner break;
88937f07e0SSascha Wildner case 2:
89*4318c66eSSascha Wildner printf("His filthy tunic hangs by one less ");
90*4318c66eSSascha Wildner puts("thread.");
91937f07e0SSascha Wildner break;
92937f07e0SSascha Wildner }
93937f07e0SSascha Wildner else if (hurt < 10) {
94937f07e0SSascha Wildner switch (rnd(3)) {
95937f07e0SSascha Wildner case 0:
96937f07e0SSascha Wildner puts("He's bleeding.");
97937f07e0SSascha Wildner break;
98937f07e0SSascha Wildner case 1:
99937f07e0SSascha Wildner puts("A trickle of blood runs down his face.");
100937f07e0SSascha Wildner break;
101937f07e0SSascha Wildner case 2:
102*4318c66eSSascha Wildner printf("A huge purple bruise is forming on ");
103*4318c66eSSascha Wildner puts("the side of his face.");
104937f07e0SSascha Wildner break;
105937f07e0SSascha Wildner }
106937f07e0SSascha Wildner lifeline++;
107937f07e0SSascha Wildner } else if (hurt < 20) {
108937f07e0SSascha Wildner switch (rnd(3)) {
109937f07e0SSascha Wildner case 0:
110937f07e0SSascha Wildner puts("He staggers back quavering.");
111937f07e0SSascha Wildner break;
112937f07e0SSascha Wildner case 1:
113*4318c66eSSascha Wildner printf("He jumps back with his hand over ");
114*4318c66eSSascha Wildner puts("the wound.");
115937f07e0SSascha Wildner break;
116937f07e0SSascha Wildner case 2:
117*4318c66eSSascha Wildner printf("His shirt falls open with a swath ");
118*4318c66eSSascha Wildner puts("across the chest.");
119937f07e0SSascha Wildner break;
120937f07e0SSascha Wildner }
121937f07e0SSascha Wildner lifeline += 5;
122937f07e0SSascha Wildner } else if (hurt < 30) {
123937f07e0SSascha Wildner switch (rnd(3)) {
124937f07e0SSascha Wildner case 0:
125*4318c66eSSascha Wildner printf("A bloody gash opens up on his %s ",
126937f07e0SSascha Wildner (rnd(2) ? "left" : "right"));
127*4318c66eSSascha Wildner printf("side.\n");
128937f07e0SSascha Wildner break;
129937f07e0SSascha Wildner case 1:
130*4318c66eSSascha Wildner printf("The steel bites home and scrapes ");
131*4318c66eSSascha Wildner puts("along his ribs.");
132937f07e0SSascha Wildner break;
133937f07e0SSascha Wildner case 2:
134*4318c66eSSascha Wildner printf("You pierce him, and his breath ");
135*4318c66eSSascha Wildner puts("hisses through clenched teeth.");
136937f07e0SSascha Wildner break;
137937f07e0SSascha Wildner }
138937f07e0SSascha Wildner lifeline += 10;
139937f07e0SSascha Wildner } else if (hurt < 40) {
140937f07e0SSascha Wildner switch (rnd(3)) {
141937f07e0SSascha Wildner case 0:
142937f07e0SSascha Wildner puts("You smite him to the ground.");
143*4318c66eSSascha Wildner if (strength - lifeline > 20) {
144*4318c66eSSascha Wildner printf("But in a flurry of steel he ");
145*4318c66eSSascha Wildner puts("regains his feet!");
146*4318c66eSSascha Wildner }
147937f07e0SSascha Wildner break;
148937f07e0SSascha Wildner case 1:
149*4318c66eSSascha Wildner printf("The force of your blow sends him to ");
150*4318c66eSSascha Wildner puts("his knees.");
151937f07e0SSascha Wildner puts("His arm swings lifeless at his side.");
152937f07e0SSascha Wildner break;
153937f07e0SSascha Wildner case 2:
154*4318c66eSSascha Wildner printf("Clutching his blood drenched shirt, ");
155*4318c66eSSascha Wildner puts("he collapses stunned.");
156937f07e0SSascha Wildner break;
157937f07e0SSascha Wildner }
158937f07e0SSascha Wildner lifeline += 20;
159937f07e0SSascha Wildner } else {
160937f07e0SSascha Wildner switch (rnd(3)) {
161937f07e0SSascha Wildner case 0:
162*4318c66eSSascha Wildner printf("His ribs crack under your powerful ");
163*4318c66eSSascha Wildner puts("swing, flooding his lungs with blood.");
164937f07e0SSascha Wildner break;
165937f07e0SSascha Wildner case 1:
166*4318c66eSSascha Wildner printf("You shatter his upheld arm in a ");
167*4318c66eSSascha Wildner printf("spray of blood. The blade ");
168*4318c66eSSascha Wildner puts("continues deep");
169*4318c66eSSascha Wildner printf("into his back, severing the ");
170*4318c66eSSascha Wildner puts("spinal cord.");
171937f07e0SSascha Wildner lifeline += 25;
172937f07e0SSascha Wildner break;
173937f07e0SSascha Wildner case 2:
174*4318c66eSSascha Wildner printf("With a mighty lunge the steel ");
175*4318c66eSSascha Wildner printf("slides in, and gasping, he falls ");
176*4318c66eSSascha Wildner puts("to the ground.");
177937f07e0SSascha Wildner lifeline += 25;
178937f07e0SSascha Wildner break;
179937f07e0SSascha Wildner }
180937f07e0SSascha Wildner lifeline += 30;
181937f07e0SSascha Wildner }
182937f07e0SSascha Wildner break;
183937f07e0SSascha Wildner
184937f07e0SSascha Wildner case BACK:
185937f07e0SSascha Wildner if (enemy == DARK && lifeline > strength * 0.33) {
186*4318c66eSSascha Wildner printf("He throws you back against the rock and ");
187*4318c66eSSascha Wildner puts("pummels your face.");
188937f07e0SSascha Wildner if (testbit(inven, AMULET) || testbit(wear, AMULET)) {
189937f07e0SSascha Wildner printf("Lifting the amulet from you, ");
190937f07e0SSascha Wildner if (testbit(inven, MEDALION) ||
191937f07e0SSascha Wildner testbit(wear, MEDALION)) {
192*4318c66eSSascha Wildner printf("his power grows and the ");
193*4318c66eSSascha Wildner printf("walls of\nthe earth ");
194*4318c66eSSascha Wildner printf("tremble.\n");
195*4318c66eSSascha Wildner printf("When he touches the ");
196*4318c66eSSascha Wildner printf("medallion, your chest ");
197*4318c66eSSascha Wildner printf("explodes and the foundations ");
198*4318c66eSSascha Wildner printf("of the\nearth collapse.\n");
199*4318c66eSSascha Wildner printf("The planet is consumed by ");
200*4318c66eSSascha Wildner puts("darkness.");
201*4318c66eSSascha Wildner die();
202937f07e0SSascha Wildner }
203937f07e0SSascha Wildner if (testbit(inven, AMULET)) {
204937f07e0SSascha Wildner clearbit(inven, AMULET);
205937f07e0SSascha Wildner carrying -= objwt[AMULET];
206937f07e0SSascha Wildner encumber -= objcumber[AMULET];
207937f07e0SSascha Wildner } else
208937f07e0SSascha Wildner clearbit(wear, AMULET);
209937f07e0SSascha Wildner puts("he flees down the dark caverns.");
210937f07e0SSascha Wildner clearbit(location[position].objects, DARK);
211937f07e0SSascha Wildner injuries[SKULL] = 1;
212*4318c66eSSascha Wildner followfight = ourtime;
213937f07e0SSascha Wildner return (0);
214937f07e0SSascha Wildner } else {
215937f07e0SSascha Wildner puts("I'm afraid you have been killed.");
216*4318c66eSSascha Wildner die();
217937f07e0SSascha Wildner }
218937f07e0SSascha Wildner } else {
219*4318c66eSSascha Wildner printf("You escape stunned and disoriented from ");
220*4318c66eSSascha Wildner puts("the fight.");
221*4318c66eSSascha Wildner printf("A victorious bellow echoes from the ");
222*4318c66eSSascha Wildner puts("battlescene.");
223937f07e0SSascha Wildner if (back && position != back)
224*4318c66eSSascha Wildner moveplayer(back, BACK);
225937f07e0SSascha Wildner else if (ahead && position != ahead)
226*4318c66eSSascha Wildner moveplayer(ahead, AHEAD);
227937f07e0SSascha Wildner else if (left && position != left)
228*4318c66eSSascha Wildner moveplayer(left, LEFT);
229937f07e0SSascha Wildner else if (right && position != right)
230*4318c66eSSascha Wildner moveplayer(right, RIGHT);
231937f07e0SSascha Wildner else
232*4318c66eSSascha Wildner moveplayer(location[position].down, AHEAD);
233937f07e0SSascha Wildner return (0);
234937f07e0SSascha Wildner }
235937f07e0SSascha Wildner
236937f07e0SSascha Wildner case SHOOT:
237937f07e0SSascha Wildner if (testbit(inven, LASER)) {
238937f07e0SSascha Wildner if (strength - lifeline <= 50) {
239937f07e0SSascha Wildner printf("The %s took a direct hit!\n",
240937f07e0SSascha Wildner objsht[enemy]);
241937f07e0SSascha Wildner lifeline += 50;
242937f07e0SSascha Wildner } else {
243*4318c66eSSascha Wildner printf("With his bare hand he deflects the ");
244*4318c66eSSascha Wildner printf("laser blast and whips the pistol ");
245*4318c66eSSascha Wildner puts("from you!");
246937f07e0SSascha Wildner clearbit(inven, LASER);
247937f07e0SSascha Wildner setbit(location[position].objects, LASER);
248937f07e0SSascha Wildner carrying -= objwt[LASER];
249937f07e0SSascha Wildner encumber -= objcumber[LASER];
250937f07e0SSascha Wildner }
251937f07e0SSascha Wildner } else
252937f07e0SSascha Wildner puts("Unfortunately, you don't have a blaster handy.");
253937f07e0SSascha Wildner break;
254937f07e0SSascha Wildner
255937f07e0SSascha Wildner case DROP:
256937f07e0SSascha Wildner case DRAW:
257937f07e0SSascha Wildner cypher();
258*4318c66eSSascha Wildner ourtime--;
259937f07e0SSascha Wildner break;
260937f07e0SSascha Wildner
261937f07e0SSascha Wildner default:
262*4318c66eSSascha Wildner puts("You don't have a chance; he is too quick.");
263937f07e0SSascha Wildner break;
264*4318c66eSSascha Wildner
265937f07e0SSascha Wildner }
266937f07e0SSascha Wildner if (lifeline >= strength) {
267937f07e0SSascha Wildner printf("You have killed the %s.\n", objsht[enemy]);
268*4318c66eSSascha Wildner if (enemy == ELF || enemy == DARK) {
269*4318c66eSSascha Wildner printf("A watery black smoke consumes his body and ");
270*4318c66eSSascha Wildner puts("then vanishes with a peal of thunder!");
271*4318c66eSSascha Wildner }
272937f07e0SSascha Wildner clearbit(location[position].objects, enemy);
273937f07e0SSascha Wildner power += 2;
274937f07e0SSascha Wildner notes[JINXED]++;
275937f07e0SSascha Wildner return (0);
276937f07e0SSascha Wildner }
277937f07e0SSascha Wildner puts("He attacks...");
278937f07e0SSascha Wildner /* Some embellishments. */
279937f07e0SSascha Wildner hurt = rnd(NUMOFINJURIES) - (testbit(inven, SHIELD) != 0) -
280937f07e0SSascha Wildner (testbit(wear, MAIL) != 0) - (testbit(wear, HELM) != 0);
281937f07e0SSascha Wildner hurt += (testbit(wear, AMULET) != 0) +
282937f07e0SSascha Wildner (testbit(wear, MEDALION) != 0) + (testbit(wear, TALISMAN) != 0);
283937f07e0SSascha Wildner hurt = hurt < 0 ? 0 : hurt;
284937f07e0SSascha Wildner hurt = hurt >= NUMOFINJURIES ? NUMOFINJURIES - 1 : hurt;
285937f07e0SSascha Wildner if (!injuries[hurt]) {
286937f07e0SSascha Wildner injuries[hurt] = 1;
287937f07e0SSascha Wildner printf("I'm afraid you have suffered %s.\n", ouch[hurt]);
288937f07e0SSascha Wildner } else
289937f07e0SSascha Wildner puts("You emerge unscathed.");
290937f07e0SSascha Wildner if (injuries[SKULL] && injuries[INCISE] && injuries[NECK]) {
291937f07e0SSascha Wildner puts("I'm afraid you have suffered fatal injuries.");
292*4318c66eSSascha Wildner die();
293937f07e0SSascha Wildner }
294937f07e0SSascha Wildner goto fighton;
295937f07e0SSascha Wildner }
296